Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/http/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Http 服务器是否可能知道TCP流具有;“已完成”;不管礼节如何?_Http_Sockets_Tcp - Fatal编程技术网

Http 服务器是否可能知道TCP流具有;“已完成”;不管礼节如何?

Http 服务器是否可能知道TCP流具有;“已完成”;不管礼节如何?,http,sockets,tcp,Http,Sockets,Tcp,服务器是否可能知道客户端已完成向其发送数据,并且现在已准备好响应,而不考虑(并且不知道)应用程序协议 编辑: 考虑创建一个代理服务器。您不能影响协议,您不知道每个协议的应用程序细节(因此您不知道流何时“结束”)。关于“客户端可能会关闭输入流”-这是真的,但显然客户端实际上并没有关闭流(与重用有关?)。这是用web浏览器进行的经验测试 不过,我可能找错了方向——对于代理服务器场景,将流复制到“另一端”的输出流就足够了吗?然而,另一端如何“知道”流已经结束 请参阅此程序: public class

服务器是否可能知道客户端已完成向其发送数据,并且现在已准备好响应,而不考虑(并且不知道)应用程序协议

编辑: 考虑创建一个代理服务器。您不能影响协议,您不知道每个协议的应用程序细节(因此您不知道流何时“结束”)。关于“客户端可能会关闭输入流”-这是真的,但显然客户端实际上并没有关闭流(与重用有关?)。这是用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: 啊! 把我放在愚蠢的角落里。忘记“启动”线程。 回到我最初的问题-我如何知道流已经结束

编辑3: 嗯,我的问题是完全不同的(与POST、传输编码和无法关闭的HttpClient恼人的内部缓存有关)。
为了公平起见,我将接受最能回答原始问题的答案。

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

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

如果“完成”表示TCP的入站或出站流已关闭(即所谓的半关闭连接),则这是可能的。如果
inputStream.read(字节)
返回-1,则入站流关闭

如果“finished”是其他意思,那么答案是否定的

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

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