TCP的连接与断开
2012-01-15 23:34
141 查看
在使用TCP连接的时候,客户端链接到服务器成功,然后正常使用closesocket断开,再次连接时失败,过一会儿再连接就可以成功,不知道为什么,google了一下,终于明白了原因。
原来在TCP连接后,主动去断开的一端会进入TIME_WAIT状态,在这个状态下,会等待2MSL的时间才会把本地申请的socket资源全部释放,否则在这段时间内是不能够再次使用之前的端口进行收发数据的。而对于某些应用来说,需要断开后立刻连接,这样就不能够成功了。这个问题无法解决,只能够去设置MSL的时间,最短可以是30s。
还有的网友回帖说,在TCP断开的时候可以采用两种断开方式,一种是优雅的断开,另一种就是强制断开。优雅的断开方式是在closesocket的时候,会发送FIN包,然后等待底层资源全部发送结束后对socket进行释放,但这个过程是异步的,所以closesocket的时候会立刻返回,释放的过程由底层自己去完成,所以同样不会立刻连接成功。而强制断开则是直接发送REST,这种方式下,服务器和客户端都会立刻断开连接,但这种方式同样会进入TIME_WAIT状态,所以一样不能解决这个问题。
查了好久也没能找到解决方法,获取这个问题只能通过调整MSL时间来规避了。
TCP连接断开的时候调用closesocket函数,已经讨论过有优雅的断开和强制断开,那么如何设置断开连接的方式呢?是通过设置socket描述符一个linger结构体属性。
linger结构体数据结构如下:
struct linger
{
int l_onoff;
int l_linger;
};
有三种组合方式:
第一种
l_onoff = 0;
l_linger忽略
这种方式下,就是在closesocket的时候立刻返回,底层会将未发送完的数据发送完成后再释放资源,也就
是优雅的退出。
第二种
l_onoff非零
l_linger = 0;
这种方式下,在调用closesocket的时候同样会立刻返回,但不会发送未发送完成的数据,而是通过一个REST包强制的关闭socket描述符,也就是强制的退出。
第三种
l_onoff非零
l_linger > 0
这种方式下,在调用closesocket的时候不会立刻返回,内核会延迟一段时间,这个时间就由l_linger得值来决定。如果超时时间到达之前,发送完未发送的数据(包括FIN包)并得到另一端的确认,closesocket会返回正确,socket描述符优雅性退出。否则,closesocket会直接返回错误值,未发送数据丢失,socket描述符被强制性退出。需要注意的时,如果socket描述符被设置为非堵塞型,则closesocket会直接返回值。
关于TCP的退出暂时了解这些,遇到问题再具体分析解决。
原来在TCP连接后,主动去断开的一端会进入TIME_WAIT状态,在这个状态下,会等待2MSL的时间才会把本地申请的socket资源全部释放,否则在这段时间内是不能够再次使用之前的端口进行收发数据的。而对于某些应用来说,需要断开后立刻连接,这样就不能够成功了。这个问题无法解决,只能够去设置MSL的时间,最短可以是30s。
还有的网友回帖说,在TCP断开的时候可以采用两种断开方式,一种是优雅的断开,另一种就是强制断开。优雅的断开方式是在closesocket的时候,会发送FIN包,然后等待底层资源全部发送结束后对socket进行释放,但这个过程是异步的,所以closesocket的时候会立刻返回,释放的过程由底层自己去完成,所以同样不会立刻连接成功。而强制断开则是直接发送REST,这种方式下,服务器和客户端都会立刻断开连接,但这种方式同样会进入TIME_WAIT状态,所以一样不能解决这个问题。
查了好久也没能找到解决方法,获取这个问题只能通过调整MSL时间来规避了。
TCP连接断开的时候调用closesocket函数,已经讨论过有优雅的断开和强制断开,那么如何设置断开连接的方式呢?是通过设置socket描述符一个linger结构体属性。
linger结构体数据结构如下:
struct linger
{
int l_onoff;
int l_linger;
};
有三种组合方式:
第一种
l_onoff = 0;
l_linger忽略
这种方式下,就是在closesocket的时候立刻返回,底层会将未发送完的数据发送完成后再释放资源,也就
是优雅的退出。
第二种
l_onoff非零
l_linger = 0;
这种方式下,在调用closesocket的时候同样会立刻返回,但不会发送未发送完成的数据,而是通过一个REST包强制的关闭socket描述符,也就是强制的退出。
第三种
l_onoff非零
l_linger > 0
这种方式下,在调用closesocket的时候不会立刻返回,内核会延迟一段时间,这个时间就由l_linger得值来决定。如果超时时间到达之前,发送完未发送的数据(包括FIN包)并得到另一端的确认,closesocket会返回正确,socket描述符优雅性退出。否则,closesocket会直接返回错误值,未发送数据丢失,socket描述符被强制性退出。需要注意的时,如果socket描述符被设置为非堵塞型,则closesocket会直接返回值。
关于TCP的退出暂时了解这些,遇到问题再具体分析解决。
相关文章推荐
- Tcp 断开连接(重要)
- TCP连接的建立和断开、滑动窗口
- TCP 建立连接和断开连接
- TCP协议三次握手连接四次握手断开和DOS攻击
- 一点细节 关于linux下tcp断开连接时的情况
- TCP连接异常断开的检测
- tcp 连接、传输、断开抓包解析
- 使用wireshark来分析tcp的三次握手和四次断开连接
- 怎样及时检测出非正常断开的TCP连接
- 详解socket通信 之 TCP连接与断开详解
- 利用tcpdump抓包工具监控TCP连接的三次握手和断开连接的四次挥手
- UNIX网络编程——TCP连接的建立和断开、滑动窗口
- tcp对连接断开的感知——保活定时器
- tcp 服务端如何判断客户端断开连接
- TCP/IP连接建立与断开
- TCP3次握手连接协议和4次握手断开连接协议
- TCP3次握手连接协议和4次握手断开连接协议
- TCP连接异常断开的检测
- tcp 服务端如何判断客户端断开连接
- Linux检测TCP连接断开的一种简单实现方法