Server.
//********************************************************************
// server.java
//********************************************************************
// Implements the server side of a Java based client/server chat system.
//
// Version History:
// 1.00 M. Ayers 2/3/97
// Base version, contains comments and 'looks nice'
//
// 1.01 M. Ayers 3/30/97
// Added filtering, tested all functions, no bugs found.
//
// 1.02 M. Ayers 4/15/97
// Multi Server, allows one server to connect to another as a
// client.
//
// 1.03 M. Ayers 4/20/97
// Tuned up server, checked for errors.
//********************************************************************
import java.io.*;
import sun.net.*;
import java.net.*;
class server extends NetworkServer //Uses Sun's networking classes.
{
String user[]; //Base global declarations.
DataInputStream net_input[];
PrintStream net_output[];
String channel_list[];
int channel_count[];
String user_type[];
String user_channel[];
String user_filter[];
String other_server;
int other_port;
String temp_string;
//Global counters.
static int channel_counter = 0;
static int perm_channel = 0;
static int update = 0;
static int maximum = 100;
static int next_user = 0;
static int port = 1111;
Socket network_client; // Networking Declarations.
DataInputStream server_input;
PrintStream server_output;
boolean connected = false;
server_writer w;
public static void main(String args[]) //Start server.
{
new server();
}
public server() //Begin server main code.
{
user = new String[maximum]; //Declare all arrays.
net_input = new DataInputStream[maximum];
net_output = new PrintStream[maximum];
channel_list = new String[maximum];
channel_count = new int[maximum];
user_type = new String[maximum];
user_channel = new String[maximum];
user_filter = new String[maximum];
try
{
read_info(); //Read startup information from file.
}
catch (IOException e)
{
System.out.println("ERROR: startup.channels file not
available.");
}
try
{
read_config(); //Read startup information from file.
}
catch (IOException e)
{
System.out.println("ERROR: server.config file not
available.");
}
try
{
startServer(port); //Bind server to port.
}
catch (Exception e)
{
System.out.println("ERROR: Unable to start server.");
return;
}
if (other_server != null)
{
if (connect()) //Check for connection creation.
{
connected = true;
w = new server_writer(this);
w.start();
}
else
{
System.out.println("Warning: Not able to connect to
server " + other_server);
}
}
System.out.println("Message: Server ready, waiting for
users...");
update = 1;
while(true) //Infinite loop.
{
if(update == 1) //Has server information been updated?
{
for (int i=perm_channel; i < channel_counter; I++)
//Check for empty channels.
{
if (channel_count[i] == 0) //Clear empty channels.
{
for(int j = 0; j < maximum; j++)
{
if ( user[j] != null)
{
if (user_type[j].equals("L"))
{
write_net_output(net_output[j],
"REMOVECHANNEL&" +
channel_list[i] );
}
}
}
for (int k=i; k < channel_counter ; k++)
{
channel_list[k] = channel_list[k+1];
channel_count[k] = channel_count[k+1];
}
channel_counter--;
}
}
for (int i=0; i < maximum ; i++)
{
if (user[i] != null)
{
System.out.println("Info: User - " + user[i] +
" Channel - " +
user_channel[i] + " Type - "
+ user_type[i]);
}
}
for (int i=0; i < maximum ; i++)
{
if (user[i] != null && user_type[i].equals("L"))
{
for (int j=0; j < channel_counter; j++)
{
write_net_output(net_output[i],
"ADDCHANNEL&" +
channel_list[j] +
"&" + channel_count[j] );
}
}
}
try
{
write_info(); //Write server status (for use by CGI).
}
catch (IOException e)
{
System.out.println("ERROR: Problem with .list
files.");
}
update = 0;
} // End update.
try
{
Thread.sleep(1000);
}
catch (InterruptedException e)
{
;
}
} // End while.
} // End server.
public void serviceRequest() //Handle user connections.
{
DataInputStream input = new DataInputStream(clientInput);
//Get client IO streams.
PrintStream output = clientOutput;
boolean new_channel = true;
for (int i=0;i < maximum ;i++ ) //Look for empty slot in table
{
if(user[i] == null)
{
next_user = i;
break;
}
}
net_input[next_user] = input;
net_output[next_user] = output;
user[next_user] = read_net_input(input).trim();
user_channel[next_user] = read_net_input(input).trim();
user_type[next_user] = "L";
if (user_channel[next_user].equals("server"))
{
user_type[next_user] = "S";
}
else
{
if (connected)
{
write_net_output(server_output, "ADDUSER&" +
user[next_user] + "&" +
user_channel[next_user]);
}
for (int k=0; k < channel_counter ; k++)
{
if (channel_list[k].equals(user_channel[next_user]))
{
channel_count[k]++;
new_channel = false;
break;
}
}
if (new_channel)
{
channel_list[channel_counter] = user_channel[next_user];
channel_count[channel_counter] = 1;
channel_counter++;
for(int i = 0; i < maximum; i++)
{
if (user[i] != null && user_type[i].equals("L"))
{
write_net_output(net_output[i], "ADDCHANNEL&" +
user_channel[next_user]);
}
}
}
}
System.out.println("Info: " + user[next_user] +
" connected on channel " +
user_channel[next_user] + " Index - " +
next_user);
(new reader(this, next_user)).start();
//Start thread to handle user request.
int c = next_user;
while (user[c] != null)
{
try
{
Thread.sleep(5000);
}
catch (InterruptedException e)
{
;
}
}
} // End serviceRequest.
String read_net_input(DataInputStream input) //Read network input,
one line at a time.
{
try
{
return input.readLine();
}
catch (IOException e)
{
return null;
}
}
void write_net_output(PrintStream output, String string)
//Write to network, one line at a time.
{
output.println(string);
output.flush();
}
void read_info() throws IOException //Read startup info.
{
RandomAccessFile f = new RandomAccessFile("startup.channels",
"r"); //Open startup.channels file.
String string;
int i =0;
string = f.readLine();
while(string != null)
{
channel_list[i] = string.trim();
System.out.println("Info: Permanent channel - " +
channel_list[i]);
i++;
string = f.readLine();
}
channel_counter = i;
perm_channel = i;
f.close();
} // End read_info.
void write_info() throws IOException //Write status files for CGI.
{
RandomAccessFile file1 = new RandomAccessFile("channel.list",
"rw"); //Open files.
RandomAccessFile file2 = new RandomAccessFile("user.list",
"rw");
RandomAccessFile file3 = new RandomAccessFile(
"user_on_channel.list", "rw");
int j = 0, k = 0;
for(int i = 0; i < channel_counter; i++)
{
file1.writeBytes(channel_list[i] + "\n" );
}
for(int i = 0; i < maximum; i++)
{
if (user[i] != null && !user[i].equals("server"))
{
file2.writeBytes(user[i] + "\n" );
j++;
}
}
for(int i = 0; i < maximum; i++)
{
if (user[i] != null && !user[i].equals("server"))
{
file3.writeBytes("User " + user[i] + " is on channel " +
user_channel[i] + "\n" );
k++;
}
}
for(int i = 0; i < maximum - channel_counter; I++)
//Pad file to clear unwanted lines.
{
file1.writeBytes("\n" );
}
for(int i = 0; i < maximum - j; i++)
{
file2.writeBytes("\n" );
}
for(int i = 0; i < maximum - k; i++)
{
file3.writeBytes("\n" );
}
file1.close();
file2.close();
file3.close();
} // End write_info
void read_config() throws IOException
{
String string;
Integer integer;
RandomAccessFile f = new RandomAccessFile("server.config", "r");
string = f.readLine();
while(string != null)
{
if (string.startsWith("port"))
{
string = string.substring(4).trim();
integer = new Integer(string);
port = integer.intValue();
}
else
{
if (string.startsWith("server"))
{
other_server = string.substring(6).trim();
string = f.readLine();
string = string.substring(11).trim();
integer = new Integer(string);
other_port = integer.intValue();
}
}
string = f.readLine();
}
f.close();
}
public void display() //Update server based on network activity.
{
String string;
string = w.net_line;
if (string.startsWith("ADDUSER&"))
{
adduser(string);
}
if (string.startsWith("REMOVEUSER&"))
{
removeuser(string);
}
if (string.startsWith("TEXT&"))
{
text(string);
}
update = 1;
} // End display.
boolean connect() //Create network to another server connaction.
{
System.out.println("Info: Connecting server to " +
other_server);
try
{
network_client = new Socket(other_server, other_port);
}
catch (IOException e)
{
System.out.println("Warning: Unable to connect to host <" +
e + ">");
return false;
}
System.out.println("Info: Connected to server");
try
{
server_input =
new DataInputStream (network_client.getInputStream());
server_output =
new PrintStream (network_client.getOutputStream());
}
catch (IOException e )
{
System.out.println("Warning: Server is NOT ready.");
return false;
}
write_net_output(server_output, "server");
write_net_output(server_output, "server");
return true;
} // End connect.
void adduser(String input)
{
boolean new_channel = true;
for (int i=0;i < maximum ;i++ ) //Look for empty slot in table
{
if(user[i] == null)
{
next_user = i;
break;
}
}
user[next_user] = input.substring(8,input.lastIndexOf("&"));
user_channel[next_user] = input.substring(input.lastIndexOf("&")
+ 1).trim();
user_type[next_user] = "R";
for (int k=0; k < channel_counter ; k++)
{
if (channel_list[k].equals(user_channel[next_user]))
{
channel_count[k]++;
new_channel = false;
break;
}
}
if (new_channel)
{
channel_list[channel_counter] = user_channel[next_user];
channel_count[channel_counter] = 1;
channel_counter++;
for(int i = 0; i < maximum; i++)
{
if( user[i] != null && user_type[i].equals("L"))
{
write_net_output(net_output[i], "ADDCHANNEL&" +
user_channel[next_user]);
}
}
}
for(int i = 0; i < maximum; i++)
{
if (user[i] != null &&
user_channel[next_user].equals(user_channel[i]) &&
user_type[i].equals("L"))
{
write_net_output(net_output[i], "ADDUSER&" +
user[next_user] );
}
}
for(int i = 0; i < maximum; i++)
{
if (user[i] != null && user_type[i].equals("S"))
{
write_net_output(net_output[i], "ADDUSER&" +
user[next_user] + "&" +
user_channel[next_user] );
}
}
}
void removeuser(String input)
{
String person;
person = input.substring(11).trim();
for (int i=0;i < maximum ;i++ )
{
if ( user[i].equals(person) )
{
next_user = i;
break;
}
}
for (int k=0; k < channel_counter ; k++)
{
if (channel_list[k].equals(user_channel[next_user]))
{
channel_count[k]--;
break;
}
}
for(int i = 0; i < maximum; i++)
{
if (user[i] != null &&
user_channel[next_user].equals(user_channel[i]) &&
user_type[i].equals("L"))
{
write_net_output(net_output[i], "REMOVEUSER&" +
user[next_user] );
}
}
for(int i = 0; i < maximum; i++)
{
if (user[i] != null && user_type[i].equals("S"))
{
write_net_output(net_output[i], "REMOVEUSER&" +
user[next_user]);
}
}
user[next_user] = null;
}
void text(String input) //Forward text to correct users.
{
String message;
String person;
int index = 0;
message = input.substring(5);
person = message.substring(0,message.indexOf(" "));
for(int i = 0; i < maximum; i++)
{
if (user[i] != null && user[i].equals(person))
{
index = i;
}
}
System.out.println("Text: Server " + other_server + " says " +
input.substring(5));
for(int i = 0; i < maximum; i++)
{
if (user[i] != null && i != index)
{
if (user_channel[index].equals(user_channel[i]) ||
user_type[i].equals("S") )
{
if (user_filter[i].indexOf(user[index]) == -1)
{
if(!user_type[i].equals("R"))
{
write_net_output(net_output[i], input);
}
}
}
}
}
}
} // End server.
class reader extends Thread //Thread created to handle user requests.
{
server s;
int index;
public reader(server s, int index) //This thread's index and link
to server.
{
this.s = s;
this.index = index;
}
public void run()
{
setPriority(MIN_PRIORITY);
s.user_filter[index] = "";
if (s.user_type[index].equals("S"))
{
for(int i = 0; i < s.maximum; i++)
{
if (s.user[i] != null && !s.user_type[i].equals("S"))
{
s.write_net_output(s.net_output[index], "ADDUSER&" +
s.user[i] + "&" +
s.user_channel[i]);
}
}
}
else
{
s.write_net_output(s.net_output [index], "TEXT&<<<< Adding
Startup information... >>>>");
//Add startup info to client.
for(int i = 0; i < s.channel_counter; i++)
{
s.write_net_output(s.net_output[index], "ADDCHANNEL&" +
s.channel_list[i]);
}
for(int i = 0; i < s.maximum; i++)
{
if (s.user[i] != null)
{
if(s.user_channel[index].equals(s.user_channel[i]) ||
s.user_type[i].equals("S") )
{
if (s.user_type[i].equals("R"))
{
s.write_net_output(s.net_output[index],
"ADDUSER&" + s.user[i] );
}
if (s.user_type[i].equals("S"))
{
s.write_net_output(s.net_output[i],
"ADDUSER&" +
s.user[index] + "&" +
s.user_channel[index]);
}
if (s.user_type[i].equals("L"))
{
s.write_net_output(s.net_output[index],
"ADDUSER&" + s.user[i] );
s.write_net_output(s.net_output[i],
"ADDUSER&" +
s.user[index] );
}
}
}
}
s.write_net_output(s.net_output [index], "TEXT&<<<< You are
now connected on channel " +
s.user_channel[index] + " >>>>");
}
s.update = 1;
while (true)
{
String string = s.read_net_input(s.net_input[index]);
//Read network.
if (string == null)
break;
System.out.println("Info: " + s.user[index] + " - " +
string);
if (string.startsWith("TEXT&")) // Handlers for events.
{
text(string);
}
if (string.startsWith("GO&"))
{
gochannel(string);
}
if (string.startsWith("ADDCHANNEL&"))
{
addchannel(string);
}
if (string.startsWith("ADDUSER&"))
{
adduser(string);
}
if (string.startsWith("REMOVEUSER&"))
{
removeuser(string);
}
if (string.startsWith("FILTER&"))
{
filter(string);
}
if (string.startsWith("UNFILTER&"))
{
unfilter(string);
}
if (string.startsWith("STATUS&"))
{
status(string);
}
} // End while.
for(int i = 0; i < s.maximum; i++) //When user quits, remove
from other user's lists.
{
if (s.user[i] != null)
{
if (s.user_channel[index].equals(s.user_channel[i]) ||
s.user_type[i].equals("S"))
{
if(!s.user_type[i].equals("R"))
{
s.write_net_output(s.net_output[i],
"REMOVEUSER&" +
s.user[index]);
}
}
}
}
if (s.connected)
{
s.write_net_output(s.server_output, "REMOVEUSER&" +
s.user[index] );
}
for (int i = 0; i < s.channel_counter ; i++)
{
if (s.channel_list[i].equals(s.user_channel[index]))
{
s.channel_count[i]--;
break;
}
}
s.update = 1;
System.out.println("Info: " + s.user[index] + " has
disconnected.");
s.user[index] = null;
} // End run.
void text(String input) //Forward text to correct users.
{
String message;
String person;
int person_index = 0;
System.out.println("Text: " + s.user[index] + " says " +
input.substring(5));
if (s.user_type[index].equals("S"))
{
message = input.substring(5);
person = message.substring(0,message.indexOf(" "));
for(int i = 0; i < s.maximum; i++)
{
if (s.user[i] != null && s.user[i].equals(person))
{
person_index = i;
}
}
for(int i = 0; i < s.maximum; i++)
{
if (s.user[i] != null && i != person_index &&
i != index)
{
if(!s.user_type[i].equals("R"))
{
if (s.user_channel[person_index].equals(
s.user_channel[i]) ||
s.user_type[i].equals("S") )
{
if (s.user_filter[i].indexOf(
s.user[person_index]) == -1)
{
s.write_net_output(s.net_output[i],
input);
}
}
}
}
}
}
else
{
for(int i = 0; i < s.maximum; i++)
{
if (s.user[i] != null && i != index)
{
if(!s.user_type[i].equals("R"))
{
if (s.user_channel[index].equals(
s.user_channel[i]) ||
s.user_type[i].equals("S") )
{
if (s.user_filter[i].indexOf(
s.user[index]) == -1)
{
s.write_net_output(s.net_output[i],
"TEXT&" +
s.user[index] +
" says: " +
input.substring(5));
}
}
}
}
}
}
if (s.connected)
{
s.write_net_output(s.server_output, "TEXT&" +
s.user[index] + " says: " +
input.substring(5));
}
}
void gochannel(String input)
//Place user on a different channel, removing from other channel
{
System.out.println("Info: User " + s.user[index] +
" is now on channel " + input.substring(3));
for (int k=0; k < s.channel_counter ; k++)
{
if (s.channel_list[k].equals(s.user_channel[index]))
{
s.channel_count[k]--;
break;
}
}
for (int k=0; k < s.channel_counter ; k++)
{
if (s.channel_list[k].equals(input.substring(3).trim()))
{
s.channel_count[k]++;
break;
}
}
for(int i = 0; i < s.maximum; i++)
{
if (s.user[i] != null &&
s.user_channel[index].equals(s.user_channel[i]))
{
if(s.user_type[i].equals("L"))
{
s.write_net_output(s.net_output[i], "REMOVEUSER&" +
s.user[index] );
}
}
}
s.user_channel[index] = input.substring(3).trim();
s.write_net_output(s.net_output[index], input);
s.write_net_output(s.net_output[index], "TEXT&<<<< You are now
on channel " + s.user_channel[index] +
" >>>>");
for(int i = 0; i < s.maximum; i++)
{
if (s.user[i] != null &&
s.user_channel[index].equals(s.user_channel[i]))
{
if(s.user_type[i].equals("L"))
{
s.write_net_output(s.net_output[i], "ADDUSER&" +
s.user[index] );
s.write_net_output(s.net_output[index], "ADDUSER&" +
s.user[i] );
}
if(s.user_type[i].equals("R"))
{
s.write_net_output(s.net_output[index], "ADDUSER&" +
s.user[i] );
}
}
else
{
if(s.user[i] != null && s.user_type[i].equals("S") )
{
s.write_net_output(s.net_output[i], "REMOVEUSER&" +
s.user[index] );
s.write_net_output(s.net_output[i], "ADDUSER&" +
s.user[index] + "&" +
s.user_channel[index] );
}
}
}
if (s.connected)
{
s.write_net_output(s.server_output, "REMOVEUSER&" +
s.user[index] );
s.write_net_output(s.server_output, "ADDUSER&" +
s.user[index] + "&" +
s.user_channel[index] );
}
s.update = 1;
}
void addchannel(String input)
//Add a new channel and move user to this channel.
{
System.out.println("Info: User " + s.user[index] +
" is now on new channel " +
input.substring(11));
boolean new_channel = true;
for (int k=0; k < s.channel_counter ; k++)
{
if (s.channel_list[k].equals(s.user_channel[index]))
{
s.channel_count[k]--;
break;
}
}
s.user_channel[index] = input.substring(11).trim();
for (int k=0; k < s.channel_counter ; k++)
{
if (s.channel_list[k].equals(s.user_channel[index]))
{
s.channel_count[k]++;
new_channel = false;
break;
}
}
if (new_channel)
{
s.channel_list[s.channel_counter] =
input.substring(11).trim();
s.channel_count[s.channel_counter] = 1;
s.channel_counter++;
for(int i = 0; i < s.maximum; i++)
{
if(s.user[i] != null && s.user_type[i].equals("L"))
{
s.write_net_output(s.net_output[i], "ADDCHANNEL&" +
s.user_channel[index]);
}
}
}
s.write_net_output(s.net_output[index], "TEXT&<<<< You are now
on channel " + s.user_channel[index] +
" >>>>");
for(int i = 0; i < s.maximum; i++)
{
if (s.user[i] != null && s.user_channel[index].equals(s.user_channel[i]))
{
if(s.user_type[i].equals("L"))
{
s.write_net_output(s.net_output[i], "ADDUSER&" +
s.user[index] );
s.write_net_output(s.net_output[index], "ADDUSER&" +
s.user[i] );
}
}
else
{
if(s.user[i] != null && s.user_type[i].equals("S") )
{
s.write_net_output(s.net_output[i], "REMOVEUSER&" +
s.user[index] );
s.write_net_output(s.net_output[i], "ADDUSER&" +
s.user[index] + "&" +
s.user_channel[index] );
}
}
}
if (s.connected)
{
s.write_net_output(s.server_output, "REMOVEUSER&" +
s.user[index] );
s.write_net_output(s.server_output, "ADDUSER&" +
s.user[index] + "&" +
s.user_channel[index] );
}
s.update = 1;
}
void filter(String input) //Filter (ignore) text from a user.
{
if (s.user_filter[index].indexOf(input.substring(7)) == -1)
{
s.user_filter[index] = s.user_filter[index] +
input.substring(7).trim() + "|";
}
s.write_net_output(s.net_output[index], input);
}
void unfilter(String input) //Unfilter a user.
{
String filter_name = input.substring(9).trim() + "|";
if (s.user_filter[index].indexOf(filter_name) != -1)
{
s.user_filter[index] = s.user_filter[index].substring(
0,s.user_filter[index].indexOf(filter_name)) +
s.user_filter[index].substring(
s.user_filter[index].indexOf(filter_name) +
filter_name.length());
}
s.write_net_output(s.net_output[index], input);
}
void status(String input) //Show server status in client window.
{
int num_users = 0;
int num_servers = 0;
for (int i=0;i < s.maximum;i++)
{
if (s.user[i] != null)
{
if (s.user_type[i].equals("S"))
{
num_servers++;
}
else
{
num_users++;
}
}
}
System.out.println("Info: User " + s.user[index] + " has
requested system status");
s.write_net_output(s.net_output[index], "TEXT&<<<< The server
has " + num_users +
" users connected. >>>>");
s.write_net_output(s.net_output[index], "TEXT&<<<< The server
has " + num_servers +
" servers connected. >>>>");
s.write_net_output(s.net_output[index], "TEXT&<<<< The server
has " + (s.maximum - num_users) +
" connections available. >>>>");
s.write_net_output(s.net_output[index], "TEXT&<<<< You are on
channel " + s.user_channel[index] +
" >>>>");
s.update = 1;
}
void adduser(String input)
{
boolean new_channel = true;
for (int i=0;i < s.maximum ;i++ ) //Look for empty slot in table
{
if(s.user[i] == null)
{
s.next_user = i;
break;
}
}
s.user[s.next_user] = input.substring(8,input.lastIndexOf("&"));
s.user_channel[s.next_user] =
input.substring(input.lastIndexOf("&") + 1).trim();
s.user_type[s.next_user] = "R";
for (int k=0; k < s.channel_counter ; k++)
{
if (s.channel_list[k].equals(s.user_channel[s.next_user]))
{
s.channel_count[k]++;
new_channel = false;
break;
}
}
if (new_channel)
{
s.channel_list[s.channel_counter] =
s.user_channel[s.next_user];
s.channel_count[s.channel_counter] = 1;
s.channel_counter++;
for(int i = 0; i < s.maximum; i++)
{
if(s.user[i] != null && s.user_type[i].equals("L"))
{
s.write_net_output(s.net_output[i], "ADDCHANNEL&" +
s.user_channel[s.next_user]);
}
}
}
for(int i = 0; i < s.maximum; i++)
{
if (s.user[i] != null &&
s.user_channel[s.next_user].equals(s.user_channel[i]) &&
s.user_type[i].equals("L"))
{
s.write_net_output(s.net_output[i], "ADDUSER&" +
s.user[s.next_user] );
}
}
for(int i = 0; i < s.maximum; i++)
{
if (s.user[i] != null && s.user_type[i].equals("S") &&
i != index)
{
s.write_net_output(s.net_output[i], "ADDUSER&" +
s.user[s.next_user] + "&" +
s.user_channel[s.next_user] );
}
}
if (s.connected)
{
s.write_net_output(s.server_output, "ADDUSER&" +
s.user[s.next_user] + "&" +
s.user_channel[s.next_user] );
}
s.update = 1;
}
void removeuser(String input)
{
String person;
person = input.substring(11).trim();
for (int i=0;i < s.maximum ;i++ ) //
{
if ( s.user[i].equals(person) )
{
s.next_user = i;
break;
}
}
for (int k=0; k < s.channel_counter ; k++)
{
if (s.channel_list[k].equals(s.user_channel[s.next_user]))
{
s.channel_count[k]--;
break;
}
}
for(int i = 0; i < s.maximum; i++)
{
if (s.user[i] != null && i != s.next_user &&
s.user_channel[s.next_user].equals(s.user_channel[i]) &&
s.user_type[i].equals("L"))
{
s.write_net_output(s.net_output[i], "REMOVEUSER&" +
s.user[s.next_user] );
}
}
for(int i = 0; i < s.maximum; i++)
{
if (s.user[i] != null && i != s.next_user &&
s.user_type[i].equals("S") && i != index)
{
s.write_net_output(s.net_output[i], "REMOVEUSER&" +
s.user[s.next_user]);
}
}
if (s.connected)
{
s.write_net_output(s.server_output, "REMOVEUSER&" +
s.user[s.next_user]);
}
s.user[s.next_user] = null;
s.update = 1;
}
} // End reader.
class server_writer extends Thread
//Thread to read from network, prevents display from blocking while
reading from network.
{
String net_line = "";
server s;
public server_writer(server s)
{
this.s = s;
}
public void run()
{
while (true)
{
String input = s.read_net_input(s.server_input);
//Read a line from the network.
net_line = input;
s.display(); //Call code in display.
}
}
} // End server_writer.