当前位置: 首页 > 工具软件 > Linger > 使用案例 >

socket选项LINGER介绍

李飞翼
2023-12-01

以winsock为例。

typedef struct linger {
  u_short l_onoff;
  u_short l_linger;
} LINGER, *PLINGER, *LPLINGER;

该选项可用来设置关闭socket的行为。

用法:

LINGER lingerStruct;
// If we're supposed to abort the connection, set the linger value
// on the socket to 0.
if (!bGraceful)
{
    lingerStruct.l_onoff = 1;
    lingerStruct.l_linger = 0;
    setsockopt(pContext->m_Socket, SOL_SOCKET, SO_LINGER,
        (char *)&lingerStruct, sizeof(lingerStruct));
}

closesocket(pContext->m_Socket);
pContext->m_Socket = INVALID_SOCKET;

主要分四种情况:

  1. l_onoff为0。则马上关闭socket(graceful),closesocket马上返回。并尽量在后台将内核发送缓冲区的数据发出去。这种情况正常四次挥手。
  2. l_onoff非0,l_linger为0。closesocket马上返回(abortive),连接重置,发送RST到对端,并且丢弃内核发送缓冲区中的数据。这种情况非正常四次挥手,不会time_wait。
  3. l_onoff非0,l_linger非0。这种情况又分为阻塞和非阻塞。
  • 对于阻塞socket,则延迟l_linger秒关闭socket,直到发完数据或超时。超时则连接重置,发送RST到对端(abortive),发完则是正常关闭(graceful)。
  • 对于非阻塞socket,如果closesocket不能立即完成,则马上返回错误WSAEWOULDBLOCK。

一般我们都是用情况1,跟不设置LINGER一样。这种情况在服务端的缺点是可能有大量处于time_wait的socket,占用服务器资源。

而对于非法连接,或者客户端已经主动关闭连接,或者服务端想要重启,我们可以使用情况2,强制关闭连接,这样可以避免time_wait。

但是根据SO上的大神建议,除了上述情况不要使用情况2。应用层定好协议,让客户端主动关闭连接。

情况3目前没怎么见过,以后再说。

 

 类似资料: