2012-04-01 258 views
2

我在编写客户端服务器应用程序。我想知道结束连接,哪一方应该决定结束它,客户端还是服务器?客户端连接或服务器端?

然后,如果例如客户端做到了,服务器是否应该保持打开状态?

假设我们对每个客户端和服务器下面的代码:

  socket = new Socket("127.0.0.1",3000); 
........ 

      socket.close(); 

  serverSocket = new ServerSocket(3000); 
      socket = serverSocket.accept(); 
...... 

      serverSocket.close(); 

编辑: 根据马特的答案,我锅中我的代码在这里,让看看为什么我的代码不工作:

一般来说,我有一个Jframe程序作为客户端,它将连接到一台服务器,当它打开,我想连接是活着的,因为它se向服务器和服务器发送信息应该对结果做出响应。但如果我不使用从服务器关闭套接字它提供了一个错误,如果我使用,一旦计算之后,关闭连接:

服务器

 private static PrintWriter toClient; 
     private static BufferedReader fromClient; 


    public static void run() throws IOException, SAXNotRecognizedException, SAXNotSupportedException, ParserConfigurationException, SAXException, XPathExpressionException 
     { 


     System.out.println("Server is waiting for connections..."); 

     while(true) 
     { 
       openStreams(); 
        processClient(); 
        closeStreams(); 
} 

    } 

的OpenStream:

public static void openStreams() throws IOException, SAXNotRecognizedException, SAXNotSupportedException, ParserConfigurationException, SAXException, XPathExpressionException 
      { 
      serverSocket = new ServerSocket(3000); 
      socket = serverSocket.accept(); 
       System.out.println("Connected"); 

      toClient = new PrintWriter(socket.getOutputStream(),true); 

      fromClient = new BufferedReader(new InputStreamReader(socket.getInputStream())); 


      } 

Closestearms :

public static void closeStreams() throws IOException 
      { 
      fromClient.close(); 
      toClient.close(); 
      socket.close(); 
      serverSocket.close(); 
       System.out.println("Disconnected"); 
     } 

我收到的错误如果我删除了closestream();

at java.net.PlainSocketImpl.bind(PlainSocketImpl.java:359) 
    at java.net.ServerSocket.bind(ServerSocket.java:319) 
    at java.net.ServerSocket.<init>(ServerSocket.java:185) 
    at java.net.ServerSocket.<init>(ServerSocket.java:97) 

回答

1

取决于您的应用程序的逻辑。两者都是有效的,你必须确保你的代码在两种情况下都是正确的,因为如果连接被“非自愿”中断(如网络丢失),它将在双方看起来好像另一方关闭了连接。

因此,您的代码必须优雅地处理这两种情况。

您的结束代码是可疑的:您关闭了监听套接字,这是不寻常的。只有当您不需要更多传入连接时(即通常在服务器上关闭服务器时),才应关闭监听套接字。
只关闭您从accept获得的套接字以结束“对话”,并且不要重新打开服务器侦听套接字。 (你得到的例外可能在这种情况下是一个“地址已在使用”见How to set reuse address option for a datagram socket in java code?对于如何避免特定问题的例子。)

+0

但林困惑,因为如果客户端,然后服务器应该做的** ** socket.close与否?反之亦然 – lonesome 2012-04-01 10:47:33

+0

一旦插座已经在一侧封闭,另将获得异常,如果它试图在其上运行需要连接到开放的方法。无论它是服务器还是客户端都无关紧要;一旦连接打开,从TCP的角度来看,两者都是相同的。 – Mat 2012-04-01 10:52:23

+0

如何阅读我的编辑?谢谢 – lonesome 2012-04-01 11:05:54

0

任何一方都可以关闭连接 - 既不是“更正确”。

但是,清除代码中的一个(似乎)误解很重要:关闭ServerSocket不关闭代表两个端点之间连接的套接字。

ServerSocket是端口上的侦听套接字。当客户端连接到该端口上的ServerSocket时,ServerSocket.accept()方法将返回(普通)套接字。您的两个端点之间的通信使用与此(普通)套接字关联的输入和输出流。

关闭的ServerSocket只是停止监听众所周知的端口上,不涉及到建立插座。

0

插座存在于客户端和服务器程序两者。关闭任何套接字都会在另一端抛出异常。