Chinaunix首页 | 论坛 | 博客
  • 博客访问: 312646
  • 博文数量: 176
  • 博客积分: 2970
  • 博客等级: 少校
  • 技术积分: 1520
  • 用 户 组: 普通用户
  • 注册时间: 2008-06-11 14:35
文章存档

2011年(10)

2010年(18)

2009年(62)

2008年(86)

我的朋友
最近访客

分类: 系统运维

2008-09-19 10:39:47

在MSDN中对shutdown函数中的Remarks部分有下面一段话,指出了如何进行一次优雅的slcket关闭:

To assure that all data is sent and received on a connected socket before it is closed, an application should use shutdown to close connection before calling closesocket. For example, to initiate a graceful disconnect:

  1. Call to register for FD_CLOSE notification.
  2. Call shutdown with how=SD_SEND.
  3. When FD_CLOSE received, call until zero returned, or SOCKET_ERROR.
  4. Call .

closesocket的行为也是随setsockopt()中参数的不同而有不同的表现,这里影响它的行为的主要就是那个linger结构。

 SO_DONTLINGER  若为真,则SO_LINGER选项被禁止。
 SO_LINGER      延迟关闭连接 struct linger 
 上面这两个选项影响close行为

     选项       间隔    关闭方式   等待关闭与否
 SO_DONTLINGER 不关心    优雅         否 
 SO_LINGER      零       强制        否
 SO_LINGER     非零      优雅        是

 若设置了SO_LINGER(亦即linger结构中的l_onoff域设为非零),并设置了零超时间隔,则closesocket()不被阻塞立即执行,不论是否有排队数据未发送或未被确认。这种关闭方式称为“强制”或“失效”关闭,因为套接口的虚电路立即被复位,且丢失了未发送的数据。在远端的recv()调用将以WSAECONNRESET出错。
 若设置了SO_LINGER并确定了非零的超时间隔,则closesocket()调用阻塞进程,直到所剩数据发送完毕或超时。这种关闭称为“优雅的”关闭。请注意如果套接口置为非阻塞且SO_LINGER设为非零超时,则closesocket()调用将以WSAEWOULDBLOCK错误返回。
 若在一个流类套接口上设置了SO_DONTLINGER(也就是说将linger结构的l_onoff域设为零),则closesocket()调用立即返回。但是,如果可能,排队的数据将在套接口关闭前发送。请注意,在这种情况下WINDOWS套接口实现将在一段不确定的时间内保留套接口以及其他资源,这对于想用所以套接口的应用程序来说有一定影响。

    所以一般来说,不应该把linger设置为SO_LINGER 并且设置timeout为0,这样的话,当本地主机调用closesocket时将会造成一个“强制”或“失效”的非优雅关闭。可以根据实际情况设置为另外两种情况。

阅读(534) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~