在我的客户端代码中,我按照以下步骤连接到套接字:
创建套接字
sockDesc = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)
连接它(在失败的情况下重试'x'时间)
connect(sockDesc, (sockaddr *) &destAddr, sizeof(destAddr))
(填写destAddr
字段后)
使用send()
/ recv()
操作的套接字:
send(sockDesc, buffer, bufferLen, 0)
recv(sockDesc, buffer, bufferLen, 0)
close()
套接字描述符并退出
close(sockDesc)
如果在send()
/ recv()
期间连接断开,我发现我可以通过返回第2步来连接。
这个解决方案好吗?我应该关闭套接字描述符并返回步骤1吗?
我无法理解的另一个有趣的观察是什么时候
我停止我的echo服务器并启动客户端。我创建一个Socket(步骤1)并调用connect()
失败(正如预期的那样),但随后我继续调用connect()
,比方说,10次。重试5次后,我启动服务器,connect()
成功。但在send()
调用期间,它会收到SIGPIPE
错误。我想知道:
1)每次connect()
失败时,是否需要创建新套接字?根据我的理解,只要我没有在套接字上执行任何send()
/ recv()
,它就像新的一样好,我可以为fd
重用相同的connect()
呼叫。
2)我不明白为什么在服务器启动并且SIGPIPE
成功时收到connect()
。
答案 0 :(得分:5)
答案 1 :(得分:4)
与断开连接相对应的套接字处于不稳定状态。通常,除非操作系统释放插槽,否则不允许再次连接。
我认为关闭()并再次连接会更好..你不必创建另一个套接字。
无论如何,请确保设置套接字的LINGER以确保传输中没有数据丢失。
请参阅http://www.gnu.org/s/libc/manual/html_node/Socket_002dLevel-Options.html#Socket_002dLevel-Options
答案 2 :(得分:4)
我认为关闭套接字是正确的做法,尽管如果不这样做它可能会有效。
未能连接的套接字可能与全新的套接字完全不同 - 这可能会在以后引起问题。我宁愿避免这种可能性,只是做一个新的。它更干净。
TCP套接字拥有很多状态,其中一些是特定于实现的,并且是从网络中获得的。
答案 3 :(得分:2)
如果连接断开并且您尝试在文件描述符上写入,则应该收到损坏的管道错误/信号。所有这一切都说明你试写的文件描述符不再让另一方的任何人阅读你发送的内容。
你可以做的是捕获信号SIGPIPE,然后通过关闭FD并返回到步骤1来处理重新连接。现在你将拥有一个可以读取和写入连接的新FD。
答案 4 :(得分:2)
如果Single UNIX Specification没有说它必须回到第2步而不是第1步,那么它碰巧在Linux上工作的事实只是一个实现细节,你会很远如果你回到第一步,你会变得更好,更便携。据我所知,规范并不保证可以回到第2步,因此,我建议你回到第1步。