I feel I may have horribly screwed this one up, and I'm again looking for some insight in to my mistakes. I'm supposed to write a multi-threaded chat server/client program that the server accepts requests and (messages) and sends them to the appropriate clients. The problem I'm having currently is that my client threads won't seem to stay connected. They do connect to begin with, then immediate disconnect and an error is thrown. Here's my code:
ChatClientThread Class:
Code:
package chatroom;
import java.io.IOException;
import java.net.Socket;
import java.util.Scanner;
/**
*
*/
public class ChatClientThread extends Thread
{
private Socket socket;
private ChatClient client;
private Scanner in;
public ChatClientThread(ChatClient c, Socket s)
{
client = c;
socket = s;
open();
start();
}
public void open()
{
try
{
in = new Scanner(socket.getInputStream());
}
catch (IOException ex)
{
System.out.println("Error Getting Input Stream: " + ex);
ex.printStackTrace();
}
}
public void close()
{
if (in != null) in.close();
}
public void run()
{
while(true)
{
client.handle(in.nextLine());
}
}
}
ChatClient Class:
Code:
package chatroom;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;
/**
*
*/
public class ChatClient implements Runnable
{
private Socket socket;
private Thread thread;
private Scanner in;
private PrintWriter output;
private ChatClientThread client;
public ChatClient(String hostname, int port)
{
try
{
System.out.println("Connecting, please wait...");
socket = new Socket(hostname, port);
System.out.println("Connected: " + socket);
}
catch (UnknownHostException ex)
{
System.out.println("Unknown Host: " + ex.getMessage());
ex.printStackTrace();
}
catch (IOException ex)
{
System.out.println("I/O Exception: " + ex.getMessage());
ex.printStackTrace();
}
}
public void run()
{
while(thread != null)
{
output.println(in.nextLine());
}
}
public void handle(String msg)
{
if(msg.equals(".exit"))
{
System.out.println("Exiting. Press RETURN.");
stop();
System.exit(0);
}
}
public void start() throws IOException
{
in = new Scanner(System.in);
output = new PrintWriter(socket.getOutputStream(), true);
if(thread == null)
{
client = new ChatClientThread(this, socket);
thread = new Thread(this);
thread.start();
}
}
public void stop()
{
try
{
if (thread != null) thread = null;
if (in != null) in.close();
if (output != null) output.close();
if (socket != null) socket.close();
}
catch (IOException ex)
{
System.out.println("Error in closing");
ex.printStackTrace();
}
}
public static void main(String args[])
{
ChatClient client = new ChatClient("localhost", 5678);
}
}
ChatServerThread Class:
Code:
package chatroom;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;
/**
*
*/
public class ChatServerThread extends Thread
{
private ChatServer server;
private Socket socket;
private int ID = -1;
private Scanner input;
private PrintWriter output;
public ChatServerThread(ChatServer serv, Socket sock)
{
super();
server = serv;
socket = sock;
ID = socket.getPort();
}
public void send(String msg) {output.println(msg);}
public int getID() {return ID;}
public void run()
{
System.out.println("server Thread " + ID + " is running");
String msg = null;
while((msg = input.nextLine()) != null)
server.handle(ID, msg);
}
public void open() throws IOException
{
input = new Scanner(socket.getInputStream());
output = new PrintWriter(socket.getOutputStream());
}
public void close() throws IOException
{
if (socket != null) socket.close();
if (input != null) input.close();
if (output != null) output.close();
}
}
ChatServer Class:
Code:
package chatroom;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
/**
*
*/
public class ChatServer implements Runnable
{
private ChatServerThread clients[] = new ChatServerThread[50];
private ServerSocket server;
private Thread thread;
private int clientCount = 0;
public ChatServer(int port)
{
try
{
System.out.println("Connecting to port " + port + ".");
server = new ServerSocket(port);
System.out.println("Server Started: " + server);
start();
}
catch (IOException ex)
{
System.out.println("Unable to connect to port " + port + ex.getMessage());
ex.printStackTrace();
}
}
public void start()
{
if (thread == null)
{
thread = new Thread(this);
thread.start();
}
}
public void stop()
{
if (thread != null)
thread = null;
}
public void run()
{
while(thread != null)
{
try
{
System.out.println("Waiting to client");
addThread(server.accept());
}
catch (IOException ex)
{
System.out.println("Server accept error: " + ex);
ex.printStackTrace();
stop();
}
}
}
private int findClient(int ID)
{
for(int i = 0; i < clientCount; i++)
if(clients[i].getID() == ID)
return i;
return -1;
}
public synchronized void handle(int ID, String input)
{
if (input.equals(".exit"))
{
clients[findClient(ID)].send(".exit");
}
else
for(int i = 0; i < clientCount; i++)
clients[i].send(ID + ": " + input);
}
public synchronized void remove(int ID)
{
int pos = findClient(ID);
if(pos >= 0)
{
ChatServerThread toDie = clients[pos];
System.out.println("Removing Client Thread " + ID + " at " + pos);
if(pos < clientCount - 1)
{
for(int i = pos + 1; i < clientCount; i++)
clients[i-1] = clients[i];
clientCount--;
}
try
{
toDie.close();
}
catch(IOException ex)
{
System.out.println("Error Closing Thread: " + ex);
ex.printStackTrace();
toDie.stop();
}
}
}
private void addThread(Socket socket)
{
if(clientCount < clients.length)
{
System.out.println("Client Accepted: " + socket);
clients[clientCount] = new ChatServerThread(this, socket);
try
{
clients[clientCount].open();
clients[clientCount].start();
clientCount++;
}
catch(IOException ex)
{
System.out.println("Error Opening Thread: " + ex);
ex.printStackTrace();
}
}
else
System.out.println("Client Refused: maximum of " + clients.length + " reached");
}
public static void main(String args[])
{
ChatServer server = new ChatServer(5678);
}
}
The Error I get is:
Code:
/*Correctly Echoed Commands Here*/
Connecting to port 5678.
Server Started: ServerSocket[addr=0.0.0.0/0.0.0.0,port=0,localport=5678]
Waiting to client
Client Accepted: Socket[addr=/127.0.0.1,port=46956,localport=5678]
Waiting to client
server Thread 46956 is running
/*Error is Here*/
Exception in thread "Thread-1" java.util.NoSuchElementException: No line found
at java.util.Scanner.nextLine(Scanner.java:1516)
at chatroom.ChatServerThread.run(ChatServerThread.java:36)
The ChatServer class will continue to run and accept clients, so I'm pretty sure I got that right. What I seem to have screwed up, based on the error messages is to make the client lay in wait for the user to type something as a message. Instead of laying in wait, it simply exits based on (I think) the above error. I'm just not sure how to fix it.
Any suggestions and/or pointers would be greatly appreciated, as always.
Thanks!