构建可靠的网络服务器之连接的建立和终止
2016-07-13 13:33
253 查看
自我感觉要构建可靠的网络服务器,TCP是如何连接,如何终止,不同阶段TCP所处状态,以及这些状态之间是如何转换的,深入了解这些内容还是很有必要的。
![](http://img.blog.csdn.net/20160713105052326)
![](http://img.blog.csdn.net/20160713111907632)
连接终止的启动,通常是由某个应用进程首先调用close()函数,来挑起的。我们称其为主动关闭,(我们以客户主动关闭为例,实际也大多是这种情况)具体行为为发送FIN。
FIN信号的发送,还表示了我这一端数据已经发送完毕。而且通常意义上,这个FIN被接收端所接收起到了一个文件结束符的作用(end-of-file),但这个文件结束符是放在接收端已排队等候该应用进程接收的任何其他数据之后,所以即使主动关闭一端不会再发送数据,但此时被动关闭一端还是有可能会继续接受到一些数据,这些数据也即排在文件结束符之前的已经排队等候该应用进程接受的其他数据。
当接受到FIN信号(记作时刻1),read函数会返回,并且接受端发送ACK信号,然后过一段时间会调用close函数并发送FIN信号(记作时刻2),注意时刻1的时候,主动端不会发送数据,被动端不会再接受数据,时刻2的时候,主动端不发送数据,但仍可以接受数据,被动端不接受数据,而且也不发送数据,算了还是以一个表格来讲吧
未完待续。。。。
从时刻一到时刻二(这之间的时间相对来说还是很长的,具体多长这个由讲到shutdown函数时再讲)数据流从被动关闭端到主动关闭端还是可以流通的,所以在这段时间内称之为半关闭。
![](http://img.blog.csdn.net/20160713152809475)
![](http://img.blog.csdn.net/20160713152924616)
TCP为一个连接定义了11种状态,具体的状态转换,就不一一赘述,图上也很清楚,读图的时候只需知道一点,是基于当前状态及在该状态下所就接收的分节从一个状态转换到另一个状态即可。
这里面一个相当有趣的状态是TIME_WAIT状态,这一状态会持续最长分节生命期的两倍(2 MSL1分钟到4分钟不止)。之所以说它有趣是因为它的存在体现了一种相对性,一方面这一状态周期存在时间是长的,1到4分钟,足以让被动关闭端发送的FIN分节即使没有到达主动关闭端,也没关系,被动端大可再发送一次,因为TIME_WAIT存在的时间“足够长”,可以等着被动关闭方再任性几次。另一方面,当短时间内建立相同的两次连接,有可能前一次连接发送的某分节还在游荡,而会影响后一次连接。而这个时候,1-4分钟是不是“很短”(相对),放心它又会马上消失。
一:三路握手
三路握手的过程发生在客户调用connect()函数开始到服务器端accept()函数返回结束共三个分节,以connect()函数为基准来开始是因为,我们默认服务器会早于客户打开,所以accept函数老早就处于阻塞状态。至于结束为什么是以accept()函数为基准,是因为准确来说,connect在第二个分节结束就会返回。 SYN J中的J代表客户将在连接中发送的数据的出事序列号,而服务器在确认(ACK)的时候会将所期待的下一个序列号J+1讲出。这就是J和J+1的含义。
二:TCP连接终止
连接终止的启动,通常是由某个应用进程首先调用close()函数,来挑起的。我们称其为主动关闭,(我们以客户主动关闭为例,实际也大多是这种情况)具体行为为发送FIN。
FIN信号的发送,还表示了我这一端数据已经发送完毕。而且通常意义上,这个FIN被接收端所接收起到了一个文件结束符的作用(end-of-file),但这个文件结束符是放在接收端已排队等候该应用进程接收的任何其他数据之后,所以即使主动关闭一端不会再发送数据,但此时被动关闭一端还是有可能会继续接受到一些数据,这些数据也即排在文件结束符之前的已经排队等候该应用进程接受的其他数据。
当接受到FIN信号(记作时刻1),read函数会返回,并且接受端发送ACK信号,然后过一段时间会调用close函数并发送FIN信号(记作时刻2),注意时刻1的时候,主动端不会发送数据,被动端不会再接受数据,时刻2的时候,主动端不发送数据,但仍可以接受数据,被动端不接受数据,而且也不发送数据,算了还是以一个表格来讲吧
未完待续。。。。
主动端发送数据 | 主动端接收数据 | 被动端发送数据 | 被动端接收数据 | |
---|---|---|---|---|
时刻一 | 否 | 是 | 是 | 是 |
时刻二 | 否 | 是 | 否 | 是 |
三:TCP状态转换
TCP为一个连接定义了11种状态,具体的状态转换,就不一一赘述,图上也很清楚,读图的时候只需知道一点,是基于当前状态及在该状态下所就接收的分节从一个状态转换到另一个状态即可。
这里面一个相当有趣的状态是TIME_WAIT状态,这一状态会持续最长分节生命期的两倍(2 MSL1分钟到4分钟不止)。之所以说它有趣是因为它的存在体现了一种相对性,一方面这一状态周期存在时间是长的,1到4分钟,足以让被动关闭端发送的FIN分节即使没有到达主动关闭端,也没关系,被动端大可再发送一次,因为TIME_WAIT存在的时间“足够长”,可以等着被动关闭方再任性几次。另一方面,当短时间内建立相同的两次连接,有可能前一次连接发送的某分节还在游荡,而会影响后一次连接。而这个时候,1-4分钟是不是“很短”(相对),放心它又会马上消失。
相关文章推荐
- TCP版backshell的VBS脚本代码
- 使用C语言编写基于TCP协议的Socket通讯程序实例分享
- TCP Wrappers防火墙介绍与封锁IP地址的方法
- c语言多进程tcp服务器示例
- win2003连接限制TCP连接限制
- PowerShell脚本开发之收发TCP消息包
- Nodejs创建TCP服务器 - king0222
- C#实现TCP连接信息统计的方法
- linux shell 脚本实现tcp/upd协议通讯(重定向应用)
- 使用C#实现基于TCP和UDP协议的网络通信程序的基本示例
- Android使用socket创建简单TCP连接的方法
- Android实现TCP客户端接收数据的方法
- Android TCP 文件客户端与服务器DEMO介绍
- Android中实现TCP和UDP传输实例
- python实现可将字符转换成大写的tcp服务器实例
- php实现TCP端口检测的方法
- Java Socket编程实例(一)- TCP基本使用
- Java Socket编程实例(三)- TCP服务端线程池
- Java实现Socket的TCP传输实例
- 实现了基于TCP的Java Socket编程实例代码