在套接字API方面主动关闭与被动关闭?

时间:2016-08-25 17:46:20

标签: c linux sockets tcp

在TCP中,我们说连接的一端执行"主动关闭"另一方执行“被动关闭”。

就Linux套接字API而言,您如何区分主动关闭和被动关闭?

例如,假设我们有两个已连接的Linux TCP套接字A和P,它们通过应用程序级协议交换信息,并且他们都知道是时候关闭它们的套接字(既不希望发送也不接收任何套接字)彼此之间或之间的更多数据。)

我们希望套接字A执行主动关闭,而P则需要被动关闭。

A和P可以做一些事情。例如:

  • call shutdown(SHUT_WR)
  • 调用recv并期望获得0返回
  • 致电关闭。
  • 别的东西

这些东西的组合以及A应按什么顺序进行?......以及这些东西的组合以及P应按什么顺序进行?

2 个答案:

答案 0 :(得分:2)

  

就Linux套接字API而言,您如何区分活动   关闭和被动关闭?

'活跃' close就是套接字首先发送FINRST数据包,通常是调用close()

  

这些东西的组合以及A应按什么顺序进行?...和   这些事情的组合以及P应按什么顺序进行?

在实践中,大部分是应用程序和应用程序协议特定的。我将描述回答您问题的最低/典型要求,但您的里程可能会因您特别想要完成的内容而有所不同。

如果你想在套接字A上的一个方向或另一个方向(或两个方向)终止通信,你可能首先在套接字A上调用shutdown()。根据你的描述,这两个程序都已经知道他们已经完成了,可能是由于应用程序协议消息,所以这可能没有必要。

必须 在套接字A上调用close()才能关闭套接字并释放文件描述符。

在插槽P上,您只需继续阅读,直到recv()返回0,然后您 必须 致电close()才能关闭套接字并释放文件描述符。

为了进一步阅读,有很多很好的教程,Beej's Guide to Network Programming非常受欢迎。

答案 1 :(得分:0)

活动打开是指明确发布connect(2)以建立与远程站点的连接。呼叫阻止,直到您在另一侧打开套接字(除非您在致电O_NONBLOCK之前发出了fcntl(2) connect(2)来电。

被动打开是指您在连接上有listen(2)套接字但尚未发出accept(2)系统调用的情况。 accept(2)调用通常会阻塞,直到您有一个完全打开的连接并为您提供一个套接字描述符来通过它进行通信,如果在发出{{{}时连接握手已经完成,则会立即为您提供套接字描述符1}}系统调用(这是被动打开)。在您准备进行accept(2)系统调用时,内核可以代表您接受的被动打开连接数量的限制是所谓的accept(2)值。

有效关闭是您明确调用listen(2)shutdown(2)系统调用时会发生的情况。与被动打开一样,你无法做任何事情来实现被动关闭(这是在幕后发生的事情,是其他方面行为的产物)。当套接字生成文件结尾条件时,您会检测到被动关闭(这是close(2)在读取时始终返回read(2)个字节)含义< em>另一端已完成0(或shutdown(2)),连接是半(或完全)关闭。当您明确close(2)shutdown(2)时,这是一个积极的关闭。

如果另一端做了明确的close(2)你继续在套接字上写,那么由于无法发送数据而导致错误(在这种情况下我们可以谈论一个被动的close(2) ---一个在我们这边没有任何明确行动的情况下发生的但是另一端可以做半关闭调用close(2)。这使得tcp仅发送shutdown(2)段并保留套接字描述符以允许线程接收传输中或尚未发送的任何待处理数据。只有当它收到并确认另一端FIN段时,它才会发出信号通知您没有更多数据在传输中。