在连接失败时重新使用套接字描述符

在我的客户端代码中,我按照以下步骤连接到一个套接字

  1. 创build一个套接字

    sockDesc = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) 
  2. 连接(如果发生故障,重试'x'时间)

     connect(sockDesc, (sockaddr *) &destAddr, sizeof(destAddr)) 

    (在填充destAddr字段之后)

  3. 使用send() / recv()操作的套接字:

     send(sockDesc, buffer, bufferLen, 0) recv(sockDesc, buffer, bufferLen, 0) 
  4. close()套接字描述符并退出

     close(sockDesc) 

如果在send() / recv()期间连接中断,我发现我可以通过返回到第2步进行连接。

这个解决scheme好吗? 我应该closures套接字描述符并返回到第1步?

我无法理解的另一个有趣的观察是,当我停止我的回声服务器,并启动客户端。 我创build一个套接字(步骤1),并调用connect()失败(如预期的),但我不断地调用connect() ,可以说,10倍。 5次重试后,我启动服务器, connect()成功。 但在send()调用期间,它收到SIGPIPE错误。 我想知道:

1)每当connect()失败时,我是否需要创build一个新的套接字? 根据我的理解,只要我没有在套接字上执行任何send() / recv() ,它就像新的一样好,我可以在connect()调用中重复使用相同的fd

2)我不明白为什么服务器启动并且connect()成功时收到SIGPIPE

Solutions Collecting From Web of "在连接失败时重新使用套接字描述符"

是的,你应该关闭并返回到步骤1:

close()关闭一个文件描述符,以便它不再引用任何文件并且可以被重用。

从这里 。

对应于断开连接的插座处于不稳定状态。 通常情况下,除非操作系统释放套接字,否则将不允许再次连接。

我认为关闭()并重新连接会更好。你不必创建另一个套接字。

无论如何,请务必设置插槽的LINGER,以确保在传输过程中不会丢失任何数据。

请参阅http://www.gnu.org/s/libc/manual/html_node/Socket_002dLevel-Options.html#Socket_002dLevel-Options

我认为关闭套接字是正确的,尽管事实上,如果你不这样做,它可能会工作。

连接失败的套接字可能与全新的套接字没有完全相同的状态 – 这可能会在稍后导致问题。 我宁愿避免这种可能性,只是做一个新的。 它更干净。

TCP套接字拥有很多状态,其中一些是特定于实现的,并从网络中调出。

如果连接中断,并且您尝试在文件描述符上进行写入,则应该得到损坏的管道错误/信号。 所有这一切都是说,你试图写入的文件描述符不再有人在另一边阅读你正在发送的内容。

你可以做的就是捕获SIGPIPE信号,然后通过关闭FD再回到步骤1来处理重新连接。现在你将拥有一个新的FD,你可以读取和写入连接。

如果单一UNIX规范没有说它必须回到步骤#2而不是步骤#1,那么它发生在Linux上的事实只是一个实现的细节,你会好得多,如果你回到步骤#1更便携。 据我所知,规范没有保证可以回到第二步,所以我建议你回到第一步。