Friday, May 2, 2014

Reading errors when disconnecting from server


Not sure this is the best topic area to put this in, but I suppose. Anyways, I've been following a tutorials on some basic Java networking, and this one in particular is about how to make a console chat (link). The information seems to be outdated (I've replaced the stop() functions with interrupt() ), but it seems to be working so far (I'll attach my modified code, since I also added a little stuff of my own). However, when I try to quit the application, it gives me errors on both the server and the client as follows:


server:



Java Code:



37974 error reading: Stream closed

(37974 is the ID)

client:



Java Code:



Listening error: Socket closed



If you look in the code, you can see where these problems occur. I'm sort of new to networking in general, so I don't understand, I thought the connection had already been terminated.

Thanks!


Here's the modified code I wrote since I can't upload it:



Java Code:



import java.net.*;
import java.io.*;
import java.lang.*;

public class Client implements Runnable {
private Socket socket = null;
private ClientThread cThread = null;
private DataOutputStream streamOut = null;
private BufferedReader console = null;
private Thread thread = null;

public static void main(String[] args) {
if(args.length != 2) {
System.out.println("Usage: java Client [server] [port]");
} else {
Client client = new Client(args[0], Integer.parseInt(args[1]));
}
}

public Client(String server, int port) {
try {
// Create a new socket connection
System.out.println("Connecting to server...");
socket = new Socket(server, port);
start();
} catch(UnknownHostException uhe) {
System.out.println("Host unknown: " + uhe.getMessage());
} catch(IOException e) {
System.out.println("Unknown exception: " + e.getMessage());
}
}

public void run() {
while(thread != null) {
try {
streamOut.writeUTF(console.readLine());
streamOut.flush();
} catch(IOException e) {
System.out.println("Sending error: " + e.getMessage());
stop();
}
}
}

public void handle(String msg) {
if(msg.equals("/quit")) {
System.out.println("Goodbye bye. Press RETURN to exit...");
stop();
} else {
System.out.println(msg);
}
}

private void start() throws IOException {
console = new BufferedReader(new InputStreamReader(System.in));
streamOut = new DataOutputStream(socket.getOutputStream());

if(thread == null) {
cThread = new ClientThread(this, socket);
thread = new Thread(this);
thread.start();
}
}

public void stop() {
if(thread != null) {
thread.interrupt();
thread = null;
}

try {
if(console != null) { console.close(); }
if(streamOut != null) { streamOut.close(); }
if(socket != null) { socket.close(); }
} catch(IOException e) {
System.out.println("Error closing...");
}

cThread.close();
cThread.interrupt();
}
}


Java Code:



import java.io.*;
import java.net.*;

public class ClientThread extends Thread {
private Socket socket = null;
private Client client = null;
private DataInputStream streamIn = null;

public ClientThread(Client _client, Socket _socket) {
client = _client;
socket = _socket;
open();
start();
}

public void open() {
try {
streamIn = new DataInputStream(socket.getInputStream());
} catch(IOException e) {
System.out.println("Error getting input stream: " + e);
client.stop();
}
}

public void close() {
try {
if(streamIn != null) { streamIn.close(); }
} catch(IOException e) {
System.out.println("Error closing input stream: " + e);
}
}

public void run() {
while(true) {
try {
client.handle(streamIn.readUTF());
} catch(IOException e) {
System.out.println("Listening error: " + e.getMessage());
client.stop();
}
}
}
}


Java Code:



import java.net.*;
import java.io.*;
import java.util.*;

public class Server implements Runnable {
// This can be changed for an ArrayList to avoid limits.
//private ServerThread clients[] = new ServerThread[50];
private ArrayList<ServerThread> clients = new ArrayList<ServerThread>();
private ServerSocket sSocket = null;
private Thread thread = null;
private int clientCount = 0;

public static void main(String[] args) {
if(args.length != 1) {
System.out.println("You are using the program incorrectly.");
} else {
Server server = new Server(Integer.parseInt(args[0]));
}
}

public Server(int port) {
try {
System.out.println("Binding to port " + port + "...");
// Try to open a port on the specified port number
sSocket = new ServerSocket(port);
System.out.println("Server started: " + sSocket);
start();
} catch(IOException e) {
System.out.println(e);
}
}

public void run() {
while(thread != null) {
try {
System.out.println("Waiting for clients...");
addThread(sSocket.accept());
} catch(IOException e) {
System.out.println("Acceptance error: " + e);
stop();
}
}
}

public void start() {
if(thread == null) {
thread = new Thread(this);
thread.start();
}
}

public void stop() {
if(thread != null) {
thread.interrupt();
thread = null;
}
}

public int findClient(int id) {
for(int i = 0; i < clientCount; i++) {
//if(clients[i].getID() == id) {
if(clients.get(i).getID() == id) {
return i;
}
}

return -1;
}

public synchronized void handle(int id, String input) {
if(input.equals("/quit")) {
//clients[findClient(id)].send("/quit");
clients.get(findClient(id)).send("/quit");
remove(id);
} else {
for(int i = 0; i < clientCount; i++) {
//if(clients[i].getID() != id) {
if(clients.get(i).getID() != id) {
//clients[i].send(id + ": " + input);
clients.get(i).send(id + ": " + input);
}
}
}
}

public synchronized void remove(int id) {
int pos = findClient(id);
if(pos >= 0) {
//ServerThread toTerminate = clients[pos];
ServerThread toTerminate = clients.get(pos);
System.out.println("Remove client thread: " + id + " at " + pos);
/**if(pos < clientCount - 1) {
for(int i = pos+1; i < clientCount; i++) {
clients[i-1] = clients[i];
}
}*/
clients.remove(pos);
clientCount--;
try {
toTerminate.close();
} catch(IOException e) {
System.out.println("Error closing thread: " + e);
}
toTerminate.interrupt();
}
}

public void addThread(Socket socket) {
clients.add(new ServerThread(this, socket));
try {
//clients[clientCount].open();
//clients[clientCount].start();
clients.get(clientCount).open();
clients.get(clientCount).start();
clientCount++;
} catch(IOException e) {
System.out.println("Error opening thread: " + e);
}

/**if(clientCount < clients.length) {
System.out.println("Client accepted: " + socket);
clients[clientCount] = new ServerThread(this, socket);
try {
clients[clientCount].open();
clients[clientCount].start();
clientCount++;
} catch(IOException e) {
System.out.println("Error opening thread: " + e);
}
} else {
System.out.println("Client refused: maximum " + clients.length + " reached.");
}*/
}
}


Java Code:



import java.net.*;
import java.io.*;

public class ServerThread extends Thread {
private Server server = null;
private Socket socket = null;
private int id = -1;
private DataInputStream streamIn = null;
private DataOutputStream streamOut = null;

public ServerThread(Server _server, Socket _socket) {
super();
this.socket = _socket;
this.server = _server;
id = socket.getPort();
}

public void send(String msg) {
try {
streamOut.writeUTF(msg);
streamOut.flush();
} catch(IOException e) {
System.out.println(id + " Error sending: " + e.getMessage());
server.remove(id);
interrupt(); // We might need to call this from the Server class
}
}

public void run() {
System.out.println("Server thread " + id + " running.");
while(true) {
try {
server.handle(id, streamIn.readUTF());
} catch(IOException e) {
System.out.println(id + " error reading: " + e.getMessage());
server.remove(id);
interrupt(); // Same as the last interrupt
}
}
}

public void open() throws IOException {
streamIn = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
streamOut = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream()));
}

public void close() throws IOException {
if(socket != null) { socket.close(); }
if(streamIn != null) { streamIn.close(); }
if(streamOut != null) { streamOut.close(); }
}

public int getID() { return id; }
}


No comments:

Post a Comment