close_wait状态和time_wait状态.pdfVIP

  • 8
  • 0
  • 约1.49万字
  • 约 9页
  • 2017-06-04 发布于河南
  • 举报
close_wait状态和time_wait状态

五事九思 (⼤连Linux主机维护) ⼤连linux维护qq群:287800525 不久前,我的Socket Client程序遇到了⼀个⾮常尴尬的错误。它本来应该在⼀个socket⻓连接上持续不断地 向服务器发送数据,如果socket连接断开,那么程序会⾃动不断地重试建⽴连接。 有⼀天发现程序在不断尝试建⽴连接,但是总是失败。⽤netstat查看,这个程序竟然有上千个socket连接处 于CLOSE_WAIT状态,以⾄于达到了上限,所以⽆法建⽴新的socket连接了。 为什么会这样呢? 它们为什么会都处在CLOSE_WAIT状态呢? CLOSE_WAIT状态的⽣成原因 ⾸先我们知道,如果我们的Client程序处于CLOSE_WAIT状态的话,说明套接字是被动关闭的! 因为如果是Server端主动断掉当前连接的话,那么双⽅关闭这个TCP连接共需要四个packet : Server FIN Client Server ACK Client 这时候Server端处于FIN_WAIT_2状态;⽽我们的程序处于CLOSE_WAIT状态。 Server FIN Client 这时Client发送FIN给Server ,Client就置为LAST_ACK状态。 Server ACK Client Server回应了ACK ,那么Client的套接字才会真正置为CLOSED状态。 我们的程序处于CLOSE_WAIT状态,⽽不是LAST_ACK状态,说明还没有发FIN给Server ,那么可能是在 关闭连接之前还有许多数据要发送或者其他事要做,导致没有发这个FIN packet。 原因知道了,那么为什么不发FIN包呢,难道会在关闭⼰⽅连接前有那么多事情要做吗? 还有⼀个问题,为什么有数千个连接都处于这个状态呢?难道那段时间内,服务器端总是主动拆除我们的 连接吗? 不管怎么样,我们必须防⽌类似情况再度发⽣! ⾸先,我们要防⽌不断开辟新的端⼝,这可以通过设置SO_REUSEADDR套接字选项做到: 重⽤本地地址和端⼝ 以前我总是⼀个端⼝不⾏,就换⼀个新的使⽤,所以导致让数千个端⼝进⼊CLOSE_WAIT状态。如果下次 还发⽣这种尴尬状况,我希望加⼀个限定,只是当前这个端⼝处于CLOSE_WAIT状态! 在调⽤ sockConnected = socket(AF_INET, SOCK_STREAM, 0); 之后,我们要设置该套接字的选项来重⽤: /// 允许重⽤本地地址和端⼝: /// 这样的好处是,即使socket断了,调⽤前⾯的socket函数也不会占⽤另⼀个,⽽是始终就是⼀个端⼝ /// 这样防⽌socket始终连接不上,那么按照原来的做法,会不断地换端⼝。 int nREUSEADDR = 1; setsockopt(sockConnected, SOL_SOCKET, SO_REUSEADDR, (const char*)nREUSEADDR, sizeof(int)); 教科书上是这么说的:这样,假如服务器关闭或者退出,造成本地地址和端⼝都处于TIME_WAIT状态,那 么SO_REUSEADDR就显得⾮常有⽤。 也许我们⽆法避免被冻结在CLOSE_WAIT状态永远不出现,但起码可以保证不会占⽤新的端⼝。 其次,我们要设置SO_LINGER套接字选项: 从容关闭还是强⾏关闭? LINGER是“拖延”的意思。 默认情况下(Win2k) ,SO_DONTLINGER套接字选项的是1;SO_LINGER选项是,linger为{l_onoff :0 , l_linger :0}。 如果在发送数据的过程中(send()没有

文档评论(0)

1亿VIP精品文档

相关文档