2011-11-20 104 views
2

服务器是否可能知道客户端已经完成数据发送并且现在已准备好进行响应 - 无论(并且没有知识)应用协议?服务器是否可能知道TCP流已经“完成”而不管协议?

编辑: 想想创建一个代理服务器。你不能影响协议,你不知道每个协议的应用细节(所以你不知道流何时“结束”)。关于“客户可能关闭输入流” - 这是真的,但显然客户并没有真正关闭流(与重用有关)。这是通过Web浏览器进行实证测试的。

虽然我可能会在错误的树上吠叫 - 对于那个代理服务器场景,不会将流复制到“另一端”的输出流就够了吗?但是,另一端如何“知道”该流已结束?

看到这个程序:

public class Test { 
public static void main(String[] args) throws IOException { 
    ServerSocket serverSocket = new ServerSocket(8081, 100, InetAddress.getByName("localhost")); 
    final Socket socket1 = new Socket("www.google.com", 80); 
    final Socket socket = serverSocket.accept(); 
    new Thread(new Runnable() { 
     public void run() { 
      try { 
       final InputStream inputStream = socket1.getInputStream(); 
       final OutputStream outputStream = socket.getOutputStream(); 
       readwrite(inputStream, outputStream, false); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
     } 
    }); 
    final InputStream inputStream = socket.getInputStream(); 
    final OutputStream outputStream1 = socket1.getOutputStream(); 
    readwrite(inputStream, outputStream1, true); 

} 

private static void readwrite(InputStream inputStream, OutputStream outputStream1, boolean x) throws IOException { 
    final byte[] bytes = new byte[4]; 
    int read = -1; 
    while ((read = inputStream.read(bytes)) != -1) { 
     System.out.println((x?"s ":"r ") + new String(bytes)); 
     outputStream1.write(bytes, 0, read); 
    } 
} 
} 

而不是做什么,你会觉得它会做(在浏览www.google.com代理)的它只是挂起。应该从google读取并写入本地套接字的线程不会检测到该输入流中的任何内容。

编辑2: DOH! 把我放在愚蠢的角落。忘了“开始”线程。 回到我原来的问题 - 我怎么知道流已经结束?

编辑3: 那么,我的问题是完全不同的(与POST,Transfer-Encoding和HttpClient恼人的内部缓存 - 不能关闭)。 为了公平起见,我会接受最好回答原始问题的答案。

回答

1

如果'已完成'表示TCP的入站或出站流已关闭(所谓的半关闭连接),则可以。如果inputStream.read(bytes)返回-1,则入境流将关闭。

如果'完成'意味着别的东西,那么答案是否定的。

如果您打算实施通用代理,那么您应该同时等待来自两个套接字的数据。并将任何传入数据写入其他套接字。 如果另一个套接字不可写,您也应该停止读取套接字。否则你必须缓冲数据。代理服务器也应该处理半关闭连接。

当传送的协议具有消息边界时,不要尝试检测,因为某些协议可能会一直向两个方向传输数据。

0

不 - 但您可以使用非阻塞式读取超时,它会告诉您没有更多数据进入。这可以解决问题。

0

客户端的TCP会话将同时具有入站和出站流。客户端可能在发送请求后关闭其出站流,并将其入站流打开以接收响应。服务器会检测到这种情况,同时仍能够回复。

相关问题