在代理上使用 HTTP 隧道时,TCP 套接字出现问题。
客户端 (C++) 打开一个到服务器 (JAVA) 的 TCP 套接字。我添加了对 HTTP 代理的支持。一切正常,客户端像这样发送“HTTP 连接”请求并在之后继续普通 TCP 连接:
CONNECT servername:5555 HTTP/1.1
Host: servername:5555
Proxy-Connection: Keep-Alive
HTTP/1.1 200
但是,如果在代理中配置了空闲超时并且没有实际发送数据,则尽管客户端每 60 秒发送一次 TCP 保活数据包,但连接会终止。空闲超时配置为 10 分钟。
TCP keep alive配置如下: WSAIoctl(socket, SIO_KEEPALIVE_VALS, &alive, sizeof(alive), NULL, 0, &dwBytesRet, NULL, NULL)
客户端 IP - 192.168.91.xxx
代理 IP - 192.168.92.yyy
244 47.133017000 192.168.91.xxx 192.168.92.yyy TCP 55 [TCP Keep-Alive] 64351 > 808 [ACK] Seq=4336 Ack=13084 Win=65700 Len=1
245 47.133336000 192.168.92.yyy 192.168.91.xxx TCP 66 [TCP Keep-Alive ACK] 808 > 64351 [ACK] Seq=13084 Ack=4337 Win=65536 Len=0 SLE=4336 SRE=4337
关于如何保持连接有任何想法吗?
我尝试添加“Connection: Keep-Alive” header ,但 HTTP1.1 应该会自动添加。无论如何它都没有帮助。
最佳答案
这是应用层的超时,例如连接空闲,因为没有发送应用程序数据。您尝试过的方法无效,因为:
Connection: keep-alive
用于通过单个连接进行多个 HTTP 请求。这不适用于此处,因为从代理的角度来看,只有一个请求 (CONNECT)。- TCP keep-alive 是为了通知对等点是否不再可达(没有关闭连接就死了或连接在中间某处断开)。它不适用于 TCP 连接仍然存在但处于空闲状态(没有应用程序数据)的情况。
为代理设置一个空闲超时是有道理的。 HTTP 的思想是,客户端发送请求,服务器发送响应。如果它在接收请求或响应时处于空闲状态,通常会出现问题(或者您的连接速度非常慢)。如果在请求和响应完成后它处于空闲状态,则关闭连接是完全有效的,即使客户端请求 Connection: keep-alive
,因为保持事件不是服务器的要求,而只是如果服务器有足够的资源,建议为更多请求保持连接打开。
关于sockets - 空闲超时后 HTTP 代理上的 TCP 套接字断开连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24882816/