开发者

set option for sockets in java

开发者 https://www.devze.com 2023-03-11 15:29 出处:网络
I have a server in Java which listens for incoming connection to a specific port. And everything works as expected, my clients connect to the server and I\'m able to send databetween them.

I have a server in Java which listens for incoming connection to a specific port. And everything works as expected, my clients connect to the server and I'm able to send data between them.

My problem is that, when I shut down my client, turn it on again and try to reconnect, it won't connect (my server stays on all the time).

For me to reconnect, I have to restart my server again.

So I tried doing this on my server side:

InetSocketAddress serverAddr = new InetSocketAddress(serverIpAddress, serverPort);
serverSocket = new ServerSocket();
serverSocket.setReuseAddress(true);
//I tries setting up a reuse option     
serverSocket.bind(serverAddr);

Even after setReuseAddress() my client won't connect unless I restart my server! Has anyone any idea of how could that be done?

EDIT2:

    try {
        while(true){

        clientSocket = serverSocket.accept();

        System.out.println("S-a conectat clientul de monitorizare!");


        os=new ObjectOutputStream(clientSocket.getOutputStream());
        try{

            coord=(Coordinate)queue.take();
            System.out.println(开发者_JAVA百科coord.getLat()+coord.getLon()+coord.getVit()+coord.getwId()+coord.getime());
        os.writeObject(coord);

        os.flush();


        }

        catch(Exception e)

        {
            e.printStackTrace();

        }
        }

    } catch (IOException e) {

        System.out.println(e);

         try {

                clientSocket.close();

                os.close();

             }catch(Exception e1) {

               e1.printStackTrace();

             }

    }

New edit:

Thread pool server:

Main:

ThreadPooledServer server = new ThreadPooledServer(queue,7001); new Thread(server).start();


ThreadPooledServer:

public class ThreadPooledServer implements Runnable {

 protected ExecutorService threadPool =
        Executors.newFixedThreadPool(5);


public void run() {

    openServerSocket();

    while (!isStopped()) {
        Socket clientSocket = null;
        try {
            System.out.println("Serverul asteapta clienti spre conectare");
            clientSocket = this.serverSocket.accept();
            clientconnection++;
            System.out.println("Serverul a acceptat clientul cu numarul:"
                    + clientconnection);


        } catch (IOException e) {
            if (isStopped()) {
                System.out.println("Server Stopped.");
                return;
            }
            throw new RuntimeException("Error accepting client connection",
                    e);
        }

    WorkerRunnable workerRunnable = new WorkerRunnable(queue,clientSocket);
    this.threadPool.execute(workerRunnable);

    }

    System.out.println("Server Stopped.");
}

public synchronized void stop() { this.isStopped = true;

    try {

    this.threadPool.shutdown();

    }


    catch (IOException e) {
        throw new RuntimeException("Error closing server", e);
    }

}

private void openServerSocket() {

    try {

        InetSocketAddress serverAddr = new InetSocketAddress(SERVERIP,
                serverPort);

        serverSocket = new ServerSocket();

        serverSocket.setReuseAddress(true);
        serverSocket.bind(serverAddr);

    } catch (IOException e) {
        throw new RuntimeException("Cannot open port", e);
    }
}

 this.serverSocket.close();


In your run method you accept one client and then go in to an endless loop, trying to write data to the ObjectOutputStream. When the client closes the connection an exception is thrown because you can no longer write to the stream. At this point we're out of the endless loop(while(true) { .. }) and the run method ends.

If you want to keep accepting clients I suggest you move the while loop to the top of your code, above the accept to be exact.

Pseudo-ish code below(note: I'm not catching any exceptions etc.):

while (true)
{
    // Wait for a client to connect..
    Socket clientSocket = serverSocket.accept();

    // Write to the client..
    ObjectOutputStream os = new ObjectOutputStream(clientSocket.getOutputStream());
    os.writeObject(coord);
    os.flush();
}


Is your server single threaded for a purpose (do you only accept one client at a time) ? Usually, servers will spawn a separate thread for every connections, so it can listen more often for incoming connections, and so if the client's connection throws any errors, it won't affect the listening socket. At the moment, your server will listen to only one connection, and if an exception occurs handling the client's connection, simply move on and never listen again. In pseudocode, a typical server is like :

Server listening thread (main thread)

try {
   create server socket and bind to port
   while server is online
      listen for incoming connections
      if the client connection is accepted [1]
         start client thread
catch exception
   handle exception
finally
   make sure the server socket is disconnected
   cleanup

Server client connection thread

write to client socket to initialize connection
try
   while scoket is opened
      read data
      data treatment
      write response
 catch exceptions
    handle exception [2]
 finally
    close client socket
    cleanup

[1] if your server handles only one client, it should refuse the connection, so the client doesn't wait for no reason

[2] if the exception is not about the socket, the client should be warned by a final write to the socket before closing it

Client thread (on the client's side)

try
   connect to server
   protocol handshake (optional) [4]
   while socket is connected
      client server communication
catch exception
    handle excpetion
finally
    close socket

[4] since the server should write to the socket first, the client should read from it for any welcome message or error messages before attempting to write anything.

0

精彩评论

暂无评论...
验证码 换一张
取 消