简体   繁体   中英

Socket not closing serverside when calling socket.close() in client JAVA

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

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.

I don't know if I understand your issue, but I would say that it is normal that it's up to the server to close the socket.

On server side (in an independent thread) you have the listening socket :

ServerSocket socketServeur = new ServerSocket(port);

Then probably (in the same thread if it is a small server) a loop accepting incoming connections (no exception management, probably the socket.close is in a finally block) :

while (! askedToClose) {
    Socket socket = socketServeur.accept();
    doSomethingWithRequest(socket);
    socket.close();
}

On the client side, you have :

Socket clientSocket = new Socket();
clientSocket.connect(new InetSocketAddress(port));
OutputStream output = clientSocket.getOutputStream();
// send something to server
InputStream input = clientSocket.getInputStream(); // will block until data is available
// reading response

The server should know when it has reached the end of the request. For example in http it could be (taken from a mockHttpServer in scala so there might be some errors but the process is the same):

void doSomethingWithRequest(Socket socket) {
    BufferedReader inputReader = new BufferedReader(new InputStreamReader(socket.getInputStream));
    StreamWriter outputWriter = new OutputStreamWriter(socket.getOutputStream);

    StringBuilder requestBuilder = new StringBuilder();
    do {
        requestBuilder.append(inputReader.read().toChar());
    } while (!requestBuilder.toString().endsWith("\r\n\r\n"));

    saveUri(getUriFromRequest(requestBuilder.toString()));

    outputWriter.write("HTTP/1.1 200 OK\r\n\r\n");
    outputWriter.flush();

    inputReader.close();
    outputWriter.close();
}

EDIT : I read the code added and I still don't get it :

  • you call Socket.close(), but this method is not static
  • you loop forever in the "server"
  • I have the impression that you use the same socket for client and server

You have 3 "sockets" :

  • the listening socket (object ServerSocket)
  • the accept socket (Object Socket sent by socketServer.accept())
  • the client socket (like above in the example)

The server open and close listening and "accept" socket, and should have no impact of bad client socket management.

Then if you want your server to accept several concurrent connections, you may add a ThreadPool for accepting connections and treating requests and responses.

Try this in your Android client code :

socket.shutdownOutput(); 
socket.close(); 

It should be better ;-)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM