1 连接握手三次

解释1:已失效的连接请求报文段

情况下如下:client发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了,以致延误到连接释放以后的某个时间才到达server。本来这是一个早已失效的报文段。但server收到此失效的连接请求报文段后,就误认为是client再次发出的一个新的连接请求。于是就向client发出确认报文段,同意建立连接。假设不采用“三次握手”,那么只要server发出确认,新的连接就建立了。由于现在client并没有发出建立连接的请求,因此不会理睬server的确认,也不会向server发送数据。但server却以为新的运输连接已经建立,并一直等待client发来数据。这样,server的很多资源就白白浪费掉了。采用“三次握手”的办法可以防止上述现象发生。例如刚才那种情况,client不会向server的确认发出确认。server由于收不到确认,就知道client并没有要求建立连接。”

解释2:

这个问题的本质是, 信道不可靠, 但是通信双发需要就某个问题达成一致. 而要解决这个问题,  无论你在消息中包含什么信息, 三次通信是
理论上的最小值. 所以三次握手不是TCP本身的要求, 而是为了满足"在不可靠信道上可靠地传输信息"这一需求所导致的. 请注意这里的本质需求,
信道不可靠, 数据传输要可靠.

0次: 显然不行
1次: A->B, A不知道B是否同意
2次: A->B, B->A. B不知道A是否收到自己的消息, 因为信道不完全可靠
3次: A->B, B->A, A->B. 两边都收到了对方的ACK, 意味着各自都了解了对方的意图, 从而可以对是否开始通信这个最简单的问题
达成一致.

2 断开四次

解释:

这是因为服务端的LISTEN状态下的SOCKET当收到SYN报文的建连请求后,它可以把ACK和SYN(ACK起应答作用,而SYN起同步作用)放在一个报文里来发送。但关闭连接时,当收到对方的FIN报文通知时,它仅仅表示对方没有数据发送给你了;但未必你所有的数据都全部发送给对方了,所以你可以未必会马上会关闭SOCKET,也即你可能还需要发送一些数据给对方之后,再发送FIN报文给对方来表示你同意现在可以关闭连接了,所以它这里的ACK报文和FIN报文多数情况下都是分开发

3 为什么说TCP是可靠连接

(1) 连接是对状态的保持,实际上就是在客户端和服务器端都维护一个变量,这个变量维护现在数据传输的状态,例如传输了哪些数据,下一次需要传输哪些数据,等等,并不是真的我们想象中的真的有什么东西连接着这两端,因为无论对于有连接还是无连接,都有网线连着呢(不包括无线网),所以连接根本就不是是否真的有什么东西把他们连接起来,真实的含义就是我上面说的,两边维护一个状态变量。

(2) UDP通讯有四个参数:源IP、源端口、目的IP和目的端口。而TCP通讯至少有有六个参数:源IP、源端口、目的IP和目的端口,以及序列号(SYN)和应答号(ACK)。(SYN为己方发的,ACK则是回应对方的。ACK=对方的SYN+1,意思是我已经收到SYN,需要你下次发送SYN+1)

序列号和应答号是TCP通讯特有的参数,TCP通讯利用序列号和应答号来保持和确认数据的关联与正确性,是在三次握手中确定的,不正确的序列号和应答号会导致无法正常通讯。因此对TCP连接的连接概念可以简单理解成为同UDP通讯相比,用序列号和应答号确定了相互之间的连接特征,来保证数据传输的正确性。

(3)TCP采用超时重传的机制来确保数据传输到对方。

4 为什么TCP四次分手中,主动关闭方最后为什么要等待2MSL之后才关闭连接

(1)保证TCP协议的全双工连接能够可靠关闭

如果Client直接CLOSED了,那么由于IP协议的不可靠性或者是其它网络原因,导致Server没有收到Client最后回复的ACK。那么Server就会在超时之后继续发送FIN,此时由于Client已经CLOSED了,就找不到与重发的FIN对应的连接,最后Server就会收到RST而不是ACK,Server就会以为是连接错误把问题报告给高层。这样的情况虽然不会造成数据丢失,但是却导致TCP协议不符合可靠连接的要求。所以,Client不是直接进入CLOSED,而是要保持TIME_WAIT,当再次收到FIN的时候,能够保证对方收到ACK,最后正确的关闭连接。

(2)保证这次连接的重复数据段从网络中消失

如果Client直接CLOSED,然后又再向Server发起一个新连接,我们不能保证这个新连接与刚关闭的连接的端口号是不同的。也就是说有可能新连接和老连接的端口号是相同的。一般来说不会发生什么问题,但是还是有特殊情况出现:假设新连接和已经关闭的老连接端口号是一样的,如果前一次连接的某些数据仍然滞留在网络中,这些延迟数据在建立新连接之后才到达Server,由于新连接和老连接的端口号是一样的,又因为TCP协议判断不同连接的依据是socket pair,于是,TCP协议就认为那个延迟的数据是属于新连接的,这样就和真正的新连接的数据包发生混淆了。所以TCP连接还要在TIME_WAIT状态等待2倍MSL,这样可以保证本次连接的所有数据都从网络中消失。

TCP协议的一些问题的更多相关文章

  1. TCP协议学习

    一.TCP参考模型  VS OSI参考模型 二.TCP/IP分层模型的四个协议层分别完成以下的功能 第一层 网络接口层 网络接口层包括用于协作IP数据在已有网络介质上传输的协议.实际上TCP/IP标准 ...

  2. 【转】TCP协议

    TCP是什么? TCP(Transmission Control Protocol 传输控制协议)是一种面向连接(连接导向)的.可靠的. 基于IP的传输层协议.TCP在IP报文的协议号是6.TCP是一 ...

  3. 闲来无事,写个基于TCP协议的Socket通讯Demo

    .Net Socket通讯可以使用Socket类,也可以使用 TcpClient. TcpListener 和 UdpClient类.我这里使用的是Socket类,Tcp协议. 程序很简单,一个命令行 ...

  4. 简单测试nginx1.90做TCP协议负载均衡的功能

    最近工作中需要做TCP层面的负载均衡,以前网站用的反向代理nginx只支持应用层的负载均衡,对于TCP协议是无能为力的,需要使用LVS(linux虚拟服务器). LVS的特点是高性能和极复杂的配置.对 ...

  5. TCP协议

    TCP是一个面向连接的协议,在发送数据之前,必须在双方之间建立一条连接. TCP首部 TCP数据封装在IP数据报中 TCP包首部 下面简单说明部分字段的作用: 端口号:通讯双方由IP地址和端口号标识. ...

  6. TCP协议的三次握手和四次挥手

    暂时需要的信息有: ACK : TCP协议规定,只有ACK=1时有效,也规定连接建立后所有发送的报文的ACK必须为1 SYN(SYNchronization) : 在连接建立时用来同步序号.当SYN= ...

  7. TCP协议三次握手和四次挥手

    http://www.cnblogs.com/rootq/articles/1377355.html TCP(Transmission Control Protocol) 传输控制协议 TCP是主机对 ...

  8. ZeroMQ接口函数之 :zmq_tcp – 使用TCP协议的ØMQ网络单播协议

    ZeroMQ 官方地址 :http://api.zeromq.org/4-1:zmq-tcp zmq_tcp(7)          ØMQ Manual - ØMQ/4.1.0 Name zmq_t ...

  9. C#网络编程之---TCP协议的同步通信(二)

    上一篇学习日记C#网络编程之--TCP协议(一)中以服务端接受客户端的请求连接结尾既然服务端已经与客户端建立了连接,那么沟通通道已经打通,载满数据的小火车就可以彼此传送和接收了.现在让我们来看看数据的 ...

  10. TCP协议学习笔记(一)首部以及TCP的三次握手连接四次挥手断开

    TCP协议是一种面向连接的.可靠的流协议. 流即不间断的数据结构.这样能够保证接收到数据顺序与发送相同.但是犹如数据间没有间隔,因此在TCP通信中,发送端应用可以在自己所要发送的消息中设置一个标示长度 ...

随机推荐

  1. [BZOJ 1044] [HAOI2008] 木棍分割 【二分 + DP】

    题目链接:BZOJ 1044 第一问是一个十分显然的二分,贪心Check(),很容易就能求出最小的最大长度 Len . 第二问求方案总数,使用 DP 求解. 使用前缀和,令 Sum[i] 为前 i 根 ...

  2. 循环队列实现(C++) Ring Buffer

    循环队列:队列有着先入先出的特性.但是对于队列如果删除队头以后剩下的空间将不会被释放,又由于队列只能由队尾插入这就导致被删除部分的空间被浪费.解决这个问题就是循环队列.循环队列顾名思义就是将队列串起来 ...

  3. 69. Sqrt(x)

    题目: Implement int sqrt(int x). Compute and return the square root of x. 链接:   http://leetcode.com/pr ...

  4. Android ActionBar中的下拉菜单

    在ActionBar中添加下拉菜单,主要有一下几个关键步骤: 1. 生成一个SpinnerAdapter,设置ActionBar的下拉菜单的菜单项 2. 实现ActionBar.OnNavigatio ...

  5. 关于Linux的windows目录的挂载

    今天,linux主机下面要增加一点空间,不想再增加硬盘,所以就在实体机里面就设置了目录共享,添加自己系统的默认账号(为了增加自己主机的安全性,我都是设置的含有标点符号的密码---这也是这次挂载不成功的 ...

  6. oracle command - creata database dbca & create network netca Demo

    #Creata database command: dbca [root@redhat4 ~]# su - oracle[oracle@redhat4 ~]$ dbca               # ...

  7. LRU缓存算法

    http://blog.csdn.net/beiyeqingteng/article/details/7010411 http://blog.csdn.net/wzy_1988/article/det ...

  8. varchar 保存英文中文区别。

    varchar在SQL Server中是采用单字节来存储数据的,中文字符存储到SQL Server中会保存为两个字节,英文字符保存到数据库中,如果字段的类型为varchar,则只会占用一个字节,而如果 ...

  9. std::ofstream由二进制流写文件的问题

    从MPQ包中读取二进制流出来然后文件写到硬盘. DWORD size = SFileGetSize(hFile); char* buffer = new char[size]; std::ofstre ...

  10. Android 按键消息处理Android 按键消息处理

    在android系统中,键盘按键事件是由SystemServer服务来管理的:然后在以消息的形式分发给应用程序处理.产生键盘按键事件则是有Linux kernel的相关驱动来实现. 键盘消息有别于其他 ...