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

Adi*_*dil 9 c sockets linux

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

  1. 创建套接字

    sockDesc = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)  
    
    Run Code Online (Sandbox Code Playgroud)
  2. 连接(在发生故障时重试'x'时间)

    connect(sockDesc, (sockaddr *) &destAddr, sizeof(destAddr))  
    
    Run Code Online (Sandbox Code Playgroud)

    (填写后填写destAddr)

  3. 使用socket进行send()/ recv()操作:

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

    close(sockDesc)  
    
    Run Code Online (Sandbox Code Playgroud)

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

这个解决方案好吗?我应该关闭套接字描述符并返回步骤1吗?

另一个我无法理解的有趣观察是当我停止我的echo服务器并启动客户端时.我创建了一个Socket(步骤1)并且调用connect()失败(正如预期的那样)但是我继续打电话connect(),比方说,10次.重试5次后,我启动服务器并connect()成功完成.但在send()通话期间它收到SIGPIPE错误.我想知道:

1)每次connect()失败都需要创建一个新套接字吗?根据我的理解,只要我没有在套接字上执行任何send()/ recv()它就像新的一样好,我可以重用它fd来进行connect()调用.

2)我不明白SIGPIPE服务器启动并connect()成功后收到的原因.

Has*_*yed 5

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

close()关闭文件描述符,以便它不再引用任何文件并可以重用.

这里开始.


Mar*_*rkR 5

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

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

TCP 套接字持有很多状态,其中一些是特定于实现的,并且是从网络中计算出来的。