关于Socket通讯中的Close_wait状态

关于Socket通讯中的Close_wait状态

文/转 编辑

编者按:使用Socket通讯,有时我们查看端口状态的时候,经常会发现Socket处于close_wait状态,从而影响系统性能,此文或许会给你一些答案。

最近遇到的一个关于socket.close的问题,在某个应用服务器出现的状况(执行netstat -np | grep tcp):

tcp        0    
 0 10.224.122.16:50158         10.224.112.58:8788
         CLOSE_WAIT

tcp        0    
 0 10.224.122.16:37655         10.224.112.58:8788
         CLOSE_WAIT

tcp        1    
 0 127.0.0.1:32713            
127.0.0.1:8080              CLOSE_WAIT

tcp       38      0
10.224.122.16:34538         10.224.125.42:443    
      CLOSE_WAIT

tcp       38      0
10.224.122.16:33394         10.224.125.42:443    
      CLOSE_WAIT

tcp        1    
 0 10.224.122.16:18882         10.224.125.10:80  
         CLOSE_WAIT

tcp        1    
 0 10.224.122.16:18637         10.224.125.10:80  
         CLOSE_WAIT

tcp        1    
 0 10.224.122.16:19655         10.224.125.12:80  
         CLOSE_WAIT

........................................

总共出现了200个CLOSE_WAIT的socket.而且这些socket长时间得不到释放.下面我们来看看为什么会出现这种大量socket的CLOSE_WAIT情况

首先我们要搞清楚的是,这个socket是谁发起的,我们可以看到122.16这台机器开了很多端口,而且端口号都很大,125.12
或者125.10上的端口都是很常见服务器端口,所以122.16上这么多CLOSE_WAIT

的socket是由122.16开启的,换句话说这台机器是传统的客户端,它会主动的请求其他机器的服务端口.

要搞清楚为什么会出现CLOSE_WAIT,那么首先我们必须要清楚CLOSE_WAIT的机制和原理.

假设我们有一个client,
一个server.

当client主动发起一个socket.close()这个时候对应TCP来说,会发生什么事情呢?如下图所示.

client首先发送一个FIN信号给server, 这个时候client变成了FIN_WAIT_1的状态, server端收到FIN之后,返回ACK,然后server端的状态变成了CLOSE_WAIT.

接着server端需要发送一个FIN给client,然后server端的状态变成了LAST_ACK,接着client返回一个ACK,然后server端的socket就被成功的关闭了.

从这里可以看到,如果由客户端主动关闭一链接,那么客户端是不会出现CLOSE_WAIT状态的.客户端主动关闭链接,那么Server端将会出现CLOSE_WAIT的状态.

而我们的服务器上,是客户端socket出现了CLOSE_WAIT,由此可见这个是由于server主动关闭了server上的socket.

那么当server主动发起一个socket.close(),这个时候又发生了一些什么事情呢.

从图中我们可以看到,如果是server主动关闭链接,那么Client则有可能进入CLOSE_WAIT,如果Client不发送FIN包,那么client就一直会处在CLOSE_WAIT状态(后面我们可以看到有参数可以调整这个时间).

那么现在我们要搞清楚的是,在第二中场景中,为什么Client不发送FIN包给server.要搞清楚这个问题,我们首先要搞清楚server是怎么发FIN包给client的,其实server就是调用了

socket.close方法而已,也就是说如果要client发送FIN包,那么client就必须调用socket.close,否则就client就一直会处在CLOSE_WAIT。

来自为知笔记(Wiz)

时间: 2024-08-30 06:58:25

关于Socket通讯中的Close_wait状态的相关文章

C#socket通讯客户端(连接状态监控,掉线重连)

public class SocketClientManager { public delegate void ConnectStateEventHandler(); public event ConnectStateEventHandler ConnectedEvent;//连接成功 public event ConnectStateEventHandler DisConnectedEvent;//连接失败 public delegate void ReceiveMsgEventHandler

close_wait状态的产生原因及解决(转)

最近测试环境server由于需要与大量的后台server交互,今天突然发现有大量的close_wait产生,于是仔细研究了一下: 如果我们的服务器程序处于CLOSE_WAIT状态的话,说明套接字是被动关闭的! 因为如果是CLIENT端主动断掉当前连接的话,那么双方关闭这个TCP连接共需要四个packet: 1.Client -> FIN  -> Server   2.Client <- ACK  <- Server   这时候Client端处于FIN_WAIT_2状态:而Serve

网络编程Socket之TCP之TIME_WAIT状态详解

下面我们用最简单的一对一的客户服务器模型来重现编程中遇到的一些问题: 初学socket的时候在编写socket程序的时候会遇到很多莫名其妙的问题,比如说bind函数返回的常见错误是EADDRINUSE 使用下面的程序重现这个状态: client: int main(int argc, const char * argv[]) { struct sockaddr_in serverAdd; bzero(&serverAdd, sizeof(serverAdd)); serverAdd.sin_fa

iOS开发socket通讯

写写socket通讯那些事儿.     socket通讯公司用于给服务器发一些指令用于控制智能家居类的设备.socket无非就是发过来发过去,至于具体内容跟服务器协商就好.接下来先说说与socket通讯配合使用的socket Tool 的mac 工具.首先打开工具(工具连接以及socket用到的文件:SocketToolfor_mac_and_Third_for_xocde_socket.zip)选择Tcp Server 然后点击创建 端口号输入一个数字,60000 把. 注意可能完成之后这个数

Linux统系统开发12 Socket API编程3 TCP状态转换 多路IO高并发select poll epoll udp组播 线程池

[本文谢绝转载原文来自http://990487026.blog.51cto.com] Linux统系统开发12 Socket API编程3 TCP状态转换 多路IO高并发select  poll  epoll udp组播 线程池 TCP 11种状态理解: 1,客户端正常发起关闭请求 2,客户端与服务端同时发起关闭请求 3,FIN_WAIT1直接转变TIME_WAIT 4,客户端接收来自服务器的关闭连接请求 多路IO转接服务器: select模型 poll模型 epoll模型 udp组播模型 线

tcp连接出现close_wait状态?可能是代码不够健壮

一.问题概述 今天遇到个小问题. 我们的程序依赖了大数据那边的服务,大数据那边提供了restful接口供我们调用. 测试反映接口有问题,我在本地重现了.找了大数据方的同事,解决了. 刚开始怕对方不认账,就用wireshark抓包了.没想到对方还挺爽快地解决了. 然后我这边重新测试,自己抓包了下,结果反而发现我方程序的一个问题. 下图,是我方和大数据方的交互数据包. 前三个为tcp连接建立,中间(序号4,5,6)为http请求响应,序号7-8为大数据方在请求完毕后关闭连接. 好了,看下面的图:(下

SO_REUSEPORT和SO_REUSEADDR与socket编程中那些关于内核自动分配的...

前言: 本文分为三个章节,第一个章节主要是翻译总结汇总一位国外的老兄在Stack Overflow上的回答,但实际上Linux发展这么多年,文中的知识点已经过时且不准确了, 在第二章中通过实验,有更加准确的描述.但是,第一章节也不是全然无用,至少在了解SO_REUSEPORT和SO_REUSEADDR的发展上是有帮助的. 在第三章节中,做实验过程中需要验证一些其他的知识点,因此在这里做一个汇总. wxy:其实就是我研究完才发现文章写的不对,又不想浪费自己的研究成果,哈哈哈哈哈,hianghian

初识Socket通讯编程(一)

一.什么是socket? 当两台计算机需要通信的时候,往往我们使用的都是TCP去实现的,但是并不会直接去操作TCP协议,通常是通过Socket进行tcp通信.Socket是操作系统提供给开发者的一个接口,通过它,就可以实现设备之间的通信. 二.TCP是如何通信的? TCP连接和断开分别会存在3次握手/4此握手的过程,并且在此过程中包含了发送数据的长度(接受数据的长度),无容置疑,这个过程是复杂的,这里我们不需要做深入的探讨.如果有兴趣,可以参考此文章,这里详细的解释了TCP通信的过程: http

Socket通讯探索(二)-socket集群

前面我们在章节“Socket通讯探索(一)”中如何实现一个tcp连接,但是这仅仅是一个最初级的BIO实现,且没有添加线程池,实际应用中很少采用这种方式,因为不得不考虑当大量的Tcp连接建立的时候,服务端如何安全稳定的运行?为什么呢? 1.BIO实现方式,是阻塞式的(上一节最后面的实现方式虽然无数据的时候,不会阻塞): 2.服务端为每条连接都开辟了一个线程进行处理,而且在连接不断开的情况下,线程不会得到释放: 基于以上情况,当有大量的连接建立的时候,服务端会开辟大量的线程处理并得不到释放,而线程会