此文章是vip文章,如何查看?  

1,点击链接获取密钥 http://nicethemes.cn/product/view29882.html

2,在下方输入文章查看密钥即可立即查看当前vip文章


Linux TCP 服务器编程(五):端口重用及TIME_WAIT

  • 时间:
  • 浏览:
  • 来源:互联网

【版权声明:转载请保留出处:blog.csdn.net/gentleliu。邮箱:shallnew*163.com】

上一节说到设置套接字选项的问题,我们这一节主要处理上一节说的“Address already in use”问题,这个问题通过设置设置一个套接字选项来解决。

这个错误提示是在bind函数调用时发生的,bind函数经常遇到这个问题:试图绑定一个已经在使用的端口。但是我们已经明确关闭进程了,这是有套接字状态TIME_WAIT引起的,该状态在套接字关闭后几分钟仍保留,在TIME_WAIT状态退出之后,套接字被删除,该地址才能重新绑定而不出问题。

首先介绍一下设置套接字选项函数setsockopt():

函数原型:

#include <sys/socket.h>
int setsockopt(int sockfd,int level, int optname, const void optval, socklen_t optlen);

sockfd - 打开的描述符。

level - 解释选项代码或特定协议的代码,如SLO_SOCKET。

optname - 套接字选项,如SO_REUSEADDR。

optval - 某变量指针。

optlen - 某变量长度。 我们只需在bind函数之前调用该函数即可.

int	on = 1;
setsockopt(sockfd, SOL_SOCKET, SO_REUSERADDR, &on, sizeof(on);

重新编译,运行,发现可以解决该问题。

 接下来说说TIME_WAIT:

主动关闭的socket端会进入TIME_WAIT状态,并且持续2MSL时间长度,MSL就是maximum segment lifetime(最大分节生命期),这是一个IP数据包能在互联网上生存的最长时间,超过这个时间将在网络中消失。MSL在RFC 1122上建议是2分钟,而源自berkeley的TCP实现传统上使用30秒,因而,TIME_WAIT状态一般维持在1-4分钟。

  IP头部有一个TTL,最大值255。尽管TTL的单位不是秒(根本和时间无关),我们仍需 假设,TTL为255的TCP报文在Internet上生存时间不能超过MSL。  TCP报文在传送过程中可能因为路由故障被迫缓冲延迟、选择非最优路径等等,结果 发送方TCP机制开始超时重传。前一个TCP报文可以称为"漫游TCP重复报文",后一个 TCP报文可以称为"超时重传TCP重复报文",作为面向连接的可靠协议,TCP实现必须 正确处理这种重复报文,因为二者可能最终都到达。 

一个通常的TCP连接终止可以用图描述如下:
client                               server

FIN M

close  -----------------> (被动关闭) 

                                      ACK M+1
            <----------------- 

                                       FIN N

            <-----------------  close

ACK N+1
            -----------------> 

为什么需要 TIME_WAIT 状态? 假设最终的ACK丢失,server将重发FIN,client必须维护TCP状态信息以便可以重发
最终的ACK,否则会发送RST,结果server认为发生错误。TCP实现必须可靠地终止连 接的两个方向(全双工关闭),client必须进入 TIME_WAIT 状态,因为client可能面 临重发最终ACK的情形。

TIME_WAIT状态存在的理由:

1)可靠地实现TCP全双工连接的终止

     在进行关闭连接四路握手协议时,最后的ACK是由主动关闭端发出的,如果这个最终的ACK丢失,服务器将重发最终的FIN,因此客户端必须维护状态信息允许它重发最终的ACK。如果不维持这个状态信息,那么客户端将响应RST分节,服务器将此分节解释成一个错误。因而,要实现TCP全双工连接的正常终止,必须处理终止序列四个分节中任何一个分节的丢失情况,主动关闭的客户端必须维持状态信息进入TIME_WAIT状态。
2)允许老的重复分节在网络中消逝

      TCP分节可能由于路由器异常而“迷途”,在迷途期间,TCP发送端可能因确认超时而重发这个分节,迷途的分节在路由器修复后也会被送到最终目的地,这个原来的迷途分节就称为lost duplicate。在关闭一个TCP连接后,马上又重新建立起一个相同的IP地址和端口之间的TCP连接,后一个连接被称为前一个连接的化身(incarnation),那么有可能出现这种情况,前一个连接的迷途重复分组在前一个连接终止后出现,从而被误解成从属于新的化身。为了避免这个情况,TCP不允许处于TIME_WAIT状态的连接启动一个新的化身,因为TIME_WAIT状态持续2MSL,就可以保证当成功建立一个TCP连接的时候,来自连接先前化身的重复分组已经在网络中消逝。



本文链接http://element-ui.cn/news/show-576788.aspx