C++ 将现有套接字重新连接到新服务器所需的最小工作量是多少?

C++ 将现有套接字重新连接到新服务器所需的最小工作量是多少?,c++,linux,sockets,C++,Linux,Sockets,给定以下伪代码 int sock = socket( AF_INET, SOCK_STREAM, 0 ); sockaddr_in si; si.sin_family = AF_INET; si.sin_port = 0; si.sin_addr.s_addr = htonl( inet_network( "127.0.0.100" ) ); bind( sock, (sockaddr*)&si, sizeof si ); ... struct sockaddr_in peer_addr

给定以下伪代码

int sock = socket( AF_INET, SOCK_STREAM, 0 );
sockaddr_in si;
si.sin_family = AF_INET;
si.sin_port = 0;
si.sin_addr.s_addr = htonl( inet_network( "127.0.0.100" ) );
bind( sock, (sockaddr*)&si, sizeof si );
...
struct sockaddr_in peer_addr;
inet_pton(AF_INET, "127.0.0.200", &peer_addr.sin_addr);
peer_addr.sin_family = AF_INET;
peer_addr.sin_port = htons( 9000 );
connect( sock, (sockaddr*)&peer_addr, sizeof peer_addr) );
…假设连接成功,然后对等方关闭其各自的套接字(与listen一起使用并由accept返回),是否可以将sock重新用作具有不同对等方地址的后续连接的参数


从实验上看,答案似乎是否定的:尽管第二个连接返回0,但我尝试连接的第二个对等点从未从accept返回。一个知识渊博的回答者能解释这里出了什么问题的本质吗?0返回值应该表示成功,那么为什么对等方可以接受从不解除阻止

我可以重复使用sock连接到第二个对等机吗?或者,第二次连接必须使用套接字新创建的套接字完成吗?我已经证实这样做是有效的

将现有套接字重新连接到新服务器所需的最小工作量是多少

无限的。这是不可能的

是否可以重用sock作为具有不同对等地址的后续连接的参数

不可以。调用connect后,即使失败,也无法重新连接TCP套接字。您必须关闭它并创建一个新的套接字。一个原因是,如果套接字未绑定,则connect会将其绑定,并且绑定是基于到目标的IP路由选择的,而第二个目标的IP路由可能不同


尽管第二个连接返回0

难以置信。你确定吗

我尝试连接的第二个对等点从未从侦听返回


听我说,你不阻塞。你是说接受吗

一个知识渊博的回答者能解释这里出了什么问题的本质吗

你必须再次表示接受,而且很难相信第二次连接返回零。在Windows上,connect应返回-1,错误号==EISCONN或WSAGetLastError==WSAEISCONN

但是,在非阻塞套接字上第二次调用“编辑连接”用于检测第一次连接是否已完成。这种技术在所有的旧书中都有,但是现在我们有了SO_错误,正确的技术是检查getsockoptSO_错误,如果您从第一次连接得到了EAGAIN/ewoolblock。当从select收到写入通知或从epoll收到写入或错误通知时,您将执行这些检查。因此,在您的案例中,第二次连接确认了第一次连接的成功,并忽略了不同的目标地址/端口

0返回值应该表示成功,那么为什么对等侦听永远不会解除阻止呢

无论外观如何,第二次连接都失败了,因此服务器没有理由做任何事情,更不用说从accept返回了

我可以重复使用sock连接到第二个对等机吗

没有

或者,第二次连接必须使用套接字新创建的套接字完成吗

是否可以重用sock作为具有不同对等地址的后续连接的参数

对于TCP套接字,不,UDP套接字是不可能的,这是允许的。TCP套接字一旦关闭,就不能再使用。您需要为每个connect调用单独的套接字调用


但是,仅在Windows上,可以重用SOCKET或WSASocket中的套接字,但前提是使用dwFlags参数设置为TF_REUSE_SOCKET将其关闭。然后可以将套接字传递到或。

侦听不会阻塞。你是说接受吗是的,我想是的。我已经更正了我的帖子。虽然第二次连接返回0…很难相信。你确定吗?对此我有把握。虽然这一观察结果使我困惑,促使我提出这个问题。不过,你的回答很中肯,很具体地回答了我的问题/困惑。请检查你的代码。connect应该返回-1,errno==EISCONN或WSAGetLastError==WSAEISCONN。在将真实代码移植到伪代码时,我想我忽略了一个我认为不相关的细节,但事实并非如此:我将套接字设置为非阻塞fcntl sock、F|SETFL、fcntl sock、F|GETFL、0|O|NONBLOCK。我认为这可以解释为什么第二个连接返回0;实际结果将在套接字变为可写时通过getsockopt…异步显示,因此_ERROR。。。。这是第二次连接返回0的合理解释吗?