I'm having problems with sockets in java. I have a ServerSocket
that is listening with accept() and spawns threads for each client-request. Communication between clients and the server works fine. I am using an inputstream to read data from clients in the serverthreads, like:
inputStream = mySocket.getInputStream();
bytes = inputStream.read(buffer);
My problem is that if I call socket.close() from the clients, nothing happens to the blocking call of bytes = inputStream.read(buffer);
, it continues to block. But it works if I close the socket from the server, then the inputStream.read(buffer);
of the client returns "-1".
SERVER-MAINTHREAD:
//SERVER MAIN THREAD, SPAWNS CLIENT THREADS
ServerSocket serverSocket = new ServerSocket(SERVERPORT);
while (listening){
new ServerThread(serverSocket.accept(), monitor).start();
}
SERVER-CLIENTTHREADS:
public class ServerThread extends Thread{
public ServerThread(Socket socket, Monitor monitor) {
this.socket = socket;
this.monitor = monitor;
}
public void run(){
byte[] buffer = new byte[1024];
int bytes;
//Listen
while(true){
try {
InputStream inputStream = socket.getInputStream();
monitor.doStuffWithOtherThreads(Object myObject);
bytes = inputStream.read(buffer); //Problem
if (bytes == -1){
System.out.println("breaks");
break;
}
byte[] readBuf = (byte[]) buffer;
String readMessage = new String(readBuf, 0, bytes);
System.out.println(readMessage);
System.out.println(bytes);
} catch (IOException e) {
System.out.println("Connection closed");
break;
}
}
}
CLIENT:
InetAddress serverAddr = InetAddress.getByName("serverhostname");
socket = new Socket(serverAddr, PORT);
socket.close(); //Close the socket connection from client. Nothing happens in the serverthread
If you want the server to close the connection, you should use shutdown(cfd, SHUT_RDWR) and close(cfd) after, NOT close(lfd) . This lets the lfd socket open, allowing the server to wait at the accept for the next incoming connection. The lfd should close at the termination of the server.
The Close method closes the remote host connection and releases all managed and unmanaged resources associated with the Socket. Upon closing, the Connected property is set to false . For connection-oriented protocols, it is recommended that you call Shutdown before calling the Close method.
One way or another, if you don't close a socket, your program will leak a file descriptor. Programs can usually only open a limited number of file descriptors, so if this happens a lot, it may turn into a problem.
The server code you posted doesn't check for -1. So either that is the problem or that isn't the real code, in which case you should post the real code for comment.
EDIT The code you have posted does not behave as you have described.
Try this in your Android client code :
socket.shutdownOutput();
socket.close();
It should be better ;-)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With