在java中设置套接字选项

发布于 2024-11-12 17:51:43 字数 3186 浏览 0 评论 0原文

我有一个 Java 服务器,它监听特定端口的传入连接。一切都按预期工作,我的客户端连接到服务器,我可以在它们之间发送数据。

我的问题是,当我关闭客户端,再次打开它并尝试重新连接时,它不会连接(我的服务器始终保持打开状态)。

为了重新连接,我必须再次重新启动服务器。

所以我尝试在服务器端执行此操作:

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

即使在 setReuseAddress() 之后,除非重新启动服务器,否则我的客户端也不会连接! 有谁知道如何做到这一点?

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(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();

             }

    }

新编辑:

线程池服务器:

主要:

ThreadPooledServer server = new ThreadPooledServer(queue,7001); 新线程(服务器).start();


ThreadPooledServer:

公共类 ThreadPooledServer 实现 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.");
}

公共同步 void stop() { this.isStopped = true;

    try {

    this.threadPool.shutdown();

    }


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

}

私有无效 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();

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(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();

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

写给空气的情书 2024-11-19 17:51:43

在您的 run 方法中,您接受一个客户端,然后进入无限循环,尝试将数据写入ObjectOutputStream。当客户端关闭连接时,会引发异常,因为您无法再写入流。此时,我们脱离了无限循环 (while(true) { .. }),并且 run 方法结束。

如果您想继续接受客户端,我建议您将 while 循环移至代码顶部,准确地说是在接受之上。

下面的伪代码(注意:我没有捕获任何异常等):

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();
}

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();
}
戏蝶舞 2024-11-19 17:51:43

您的服务器是否出于某种目的而采用单线程(您一次只接受一个客户端)?通常,服务器会为每个连接生成一个单独的线程,因此它可以更频繁地侦听传入连接,因此如果客户端的连接抛出任何错误,也不会影响侦听套接字。目前,您的服务器将仅侦听一个连接,如果处理客户端连接时发生异常,只需继续前进,不再侦听。在伪代码中,典型的服务器如下:

服务器侦听线程 (主线程)

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

服务器客户端连接线程

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] 如果你的服务器只处理一个客户端,它应该拒绝连接,这样客户端就不会无缘无故地等待

[2] 如果异常与套接字无关,则应该通过以下方式警告客户端在关闭套接字之前对套接字进行最终写入

客户端线程(在客户端)

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

[4],因为服务器应该首先写入套接字,客户端应该在尝试写入任何内容之前从中读取任何欢迎消息或错误消息。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文