connect()失败后套接字是否无法使用?

Jim*_*imm 8 c linux networking tcp

在史蒂文的"The Socket:Networking API,第三版"第4章第4.3段中,作者陈述如下

"If connect fails, the socket is no longer usable and must be closed. 
 We cannot call connect again on the socket."
Run Code Online (Sandbox Code Playgroud)

有谁知道上述声明背后的原因?

在我自己的实验中,我编写了一个简单的tcp客户端,它将在主机A和一个简单的tcp服务器上运行,它将在主机B上运行.tcp客户端将尝试永远连接到主机B上的tcp服务器.

所以,我在主机B上启动了服务器.从主机上拔下网络线.然后我在主机A上启动了客户端.在同一个套接字上大约9次连接尝试失败后,我只需将网络线插回服务器主机.客户端连接成功,愉快地以80K /秒的速度发送消息.

在另一个实验中,我在初始成功连接和之后几百万条消息交换后从服务器主机拔出电线.然后,几分钟后,我连接了电线,并在同一插座上恢复了消息流.

Art*_*cto 6

POSIX 2001 在一个信息部分:

如果connect()失败,则未指定套接字的状态.在尝试重新连接之前,符合应用程序应关闭文件描述符并创建新套接字.

因此,您引用的段落与此规范一致.它在您的机器上运行的事实并不意味着您的程序是可移植的.

  • @Jimm:你没有看到你正在使用的实现"正好相反".**没有可能的"反向"未指定的行为** - 当规范确实_不说任何事情_关于在两次调用connect()时实现必须如何反应,实现_perfectly allowed_选择忘记早期的连接尝试.或者它可能会失败并显示错误消息或段错误,或终止所有进程并删除主目录,或连接到其他服务器,或者在随机破坏地址空间时似乎正常工作.这取决于它,不是你! (2认同)

Hen*_*olm 1

您确定您使用的是相同的套接字,而不是尝试连接到与以前相同的地址的新套接字吗?

即使这就是您正在做的事情,您正在试验的特定操作系统允许重用连接失败的套接字这一事实并不意味着实现套接字 API(或早期/更高版本)的所有其他操作系统相同操作系统的版本)也会同样宽松,因此您可能会冒着生成微妙的不可移植代码的风险。

当您执行 API 合约未承诺有效的操作时,通常不知道会发生什么。一种可能的反应是,它看起来会起作用——直到付费客户尝试在他的机器上运行你的代码的那一刻。

close(socket); socket=socket(...);在相当罕见的错误情况下,这种风险真的值得付出代价吗?