有没有一种方法可以检测到TCP套接字已被远程对等方关闭,而无需从中读取? [英] Is there a way to detect that TCP socket has been closed by the remote peer, without reading from it?

查看:187
本文介绍了有没有一种方法可以检测到TCP套接字已被远程对等方关闭,而无需从中读取?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

首先,有一点背景可以解释这种动机:我正在研究一个非常简单的基于select()的TCP镜像代理",该协议允许两个受防火墙保护的客户端间接相互通信.两个客户端都连接到该服务器,并且两个客户端都连接后,客户端A发送到服务器的任何TCP字节都会转发到客户端B,反之亦然.

First, a little background to explain the motivation: I'm working on a very simple select()-based TCP "mirror proxy", that allows two firewalled clients to talk to each other indirectly. Both clients connect to this server, and as soon as both clients are connected, any TCP bytes sent to the server by client A is forwarded to client B, and vice-versa.

这或多或少地起作用,但有一点点麻烦:如果客户端A连接到服务器并在客户端B连接之前开始发送数据,则服务器无处可放置数据.我不想将其缓冲在RAM中,因为那样可能最终会占用大量RAM.而且我也不想删除数据,因为客户端B可能需要它.因此,我选择了第三个选项,即在客户端B也已连接之前,不要在客户端A的套接字上进行select()-read-ready-ready准备.这样,客户端A就会阻塞,直到一切准备就绪为止.

This more or less works, with one slight gotcha: if client A connects to the server and starts sending data before client B has connected, the server doesn't have anywhere to put the data. I don't want to buffer it up in RAM, since that could end up using a lot of RAM; and I don't want to just drop the data either, as client B might need it. So I go for the third option, which is to not select()-for-read-ready on client A's socket until client B has also connected. That way client A just blocks until everything is ready to go.

或多或少也可以,但是在客户端A的套接字上不选择读-准备就绪"的副作用是,如果客户端A决定关闭与服务器的TCP连接,则不会收到有关该服务器的通知.这个事实-至少直到客户端B出现并且服务器最终选择客户端A的套接字上的Read-read-ready,读取所有挂起的数据,然后获取套接字关闭的通知(即recv()返回0)后,这一事实

That more or less works too, but the side effect of not selecting-for-read-ready on client A's socket is that if client A decides to close his TCP connection to the server, the server doesn't get notified about that fact -- at least, not until client B comes along and the server finally selects-for-read-ready on client A's socket, reads any pending data, and then gets the socket-closed notification (i.e. recv() returning 0).

如果服务器能够(及时)知道客户端A关闭其TCP连接时的某种方式,我希望使用它.有没有办法知道这一点?在这种情况下,轮询是可以接受的(例如,我可以让select()每分钟醒来一次,并在所有套接字上调用IsSocketStillConnected(sock)(如果存在这样的函数).

I'd prefer it if the server had some way of knowing (in a timely manner) when client A closed his TCP connection. Is there a way to know this? Polling would be acceptable in this case (e.g. I could have select() wake up once a minute and call IsSocketStillConnected(sock) on all sockets, if such a function existed).

推荐答案

看来,我的问题的答案是不,除非您愿意并能够修改TCP堆栈以访问必要的专用套接字状态,否则请不要.信息".

It appears the answer to my question is "no, not unless you are willing and able to modify your TCP stack to get access to the necessary private socket-state information".

由于无法执行此操作,因此我的解决方案是重新设计代理服务器,以始终从所有客户端读取数据,并丢弃来自尚未连接其伙伴的客户端的数据.这不是最优的,因为这意味着通过代理的TCP流不再具有使用TCP的程序所期望的可靠按顺序传递的类似流的属性,但这足以满足我的目的.

Since I'm not able to do that, my solution was to redesign the proxy server to always read data from all clients, and throw away any data that arrives from a client whose partner hasn't connected yet. This is non-optimal, since it means that the TCP streams going through the proxy no longer have the stream-like property of reliable in-order delivery that TCP-using programs expect, but it will suffice for my purpose.

这篇关于有没有一种方法可以检测到TCP套接字已被远程对等方关闭,而无需从中读取?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆