套接字编程:客户端断开连接使服务器挂起

时间:2018-05-09 12:53:30

标签: java c sockets server client

我正在尝试构建一个TCP转发器示例。以下是功能简介:

  1. 转发器将在给定端口侦听。
  2. 它包含客户端到服务器的地图
  3. 客户端将连接到转发器,转发器将查找地图并创建双向转发连接。
  4. 为实现此目的,它为每个客户端创建两个线程。
  5. 线程1:从客户端读取并写入目标服务器
  6. 线程2:从目标服务器读取并写入客户端。
  7. 这一切都是用C写的。 客户端和目标服务器可以用任何语言编写,现在是Java。

    当我第一次运行客户端时,它按预期工作。但是,如果我终止客户端并重新启动它,则服务器永远不会收到新连接。

    这是我怀疑是错误的服务器代码。

    Socket clientSocket = serverSocket.accept();
    InputStream inputStream = clientSocket.getInputStream();
    OutputStream outputStream = clientSocket.getOutputStream();
    
    while (true) {
        byte[] bArray = new byte[2048];
        try {
            System.out.println(String.format("SERVER:%s: Attempting to read", this.name));
            inputStream.read(bArray);
            System.out.println(String.format("SERVER:%s: Received %s", this.name, new String(bArray)));
            byte[] bytes = (name + ":" + counter).getBytes();
            counter++;
            outputStream.write(bytes);
            System.out.println(String.format("SERVER:%s: Sent %s", this.name, new String(bytes)));
        } catch (IOException e) {
            System.out.println(String.format("SERVER:%s: Client Disconnected ", this.name));
            clientSocket = serverSocket.accept();
            inputStream = clientSocket.getInputStream();
        }
    }
    

    在C程序中,我检测到断开并关闭套接字,如下所示:

    LOGINFO("Reading from Client Socket.");
    iResult = read(readSocket, buff, recvbuflen);
    if (iResult <= 0) {
        LOGERROR("Receiving failed");
        close(readSocket);          
        break;
    }
    

2 个答案:

答案 0 :(得分:1)

尝试使用并发来管理每个请求来修改服务器逻辑。通过这种方式,服务器将能够在一个线程中单独处理每个客户端。必须在相关的线程中执行读写数据。池线程范例通常用于避免线程开销[1]

例如:

ExecutorService threadPool = Executors.newFixedThreadPool(n);
ServerSocket serverSocket = null;

//...

while(!isStopped()){
   Socket clientSocket = null;
   try {
       clientSocket = this.serverSocket.accept();
       threadPool.execute(new WorkerRunnable(clientSocket));
       // Process data in the WorkerRunnable class
   } catch (IOException e) {
       if(isStopped()) {
           System.err.println("Server Stopped.") ;
           break;
       }
       throw new RuntimeException("Error accepting client connection", e);
   } 
}

可在此处找到精心设计的示例:http://tutorials.jenkov.com/java-multithreaded-servers/thread-pooled-server.html

答案 1 :(得分:1)

你应该使用

   shutdown(socket_fd, SHUT_WR);

而不是close(socket_fd)才能正确关闭套接字。

如果您使用SHUT_WR,FIN数据包将被发送到另一方通知他们我们没有更多数据要发送。