TCP协议讲解(二)——三次握手和四次挥手

关于TCP协议报文格式及相关解释和传递数据的方式,可以移步我的另一边文章:TCP协议讲解(一)
我们说TCP提供了一种面向连接的、可靠的字节流服务,面向连接指的就是每次传输数据前,都要建立连接;

可靠性:

1.应用数据被分割成TCP认为最适合发送的数据块。这和UDP完全不同,应用程序产生的数据报长度不变。

2.当TCP发出一个段后,它启动一个定时器,等待目地端确认收到报文段。如果不能及时收到一个确认,将重发这个报文。

3.当TCP收到另一端的数据,他将发送一个确认,但并不是立即确认,将推迟几分之一秒。

4.TCP将保持它首部和数据的检验和,这是一个端到端的检验和,目的是检测数据字传输过程中的任何变化。如果收到的检验和有误,TCP将丢失这个报文段和不确认收到此报文段(希望发送端超时重发)。

5.IP数据可能会失序,那TCP作为上层协议,如有必要,可以对数据进行重排序,再向上提交。

6.IP数据有可能重复,则TCP接收端必须丢弃重复数据。

7.TCP控制流量,固定的缓冲区只允许另一端发送接收端可以接纳的数据,这将导致较快主机致使较慢主机的缓冲区溢出。

面向连接:

TCP的三次握手和四次挥手:

三次握手:
三次握手

三次握手的原理与上一篇一致,A发送seq=200,SYN=1给B,A进入SYN_SEND状态,B回复时ACK=1,表示此次为回复,并将seq=201,同时SYN=1,在发送seq=500,B进入SYN_RECE状态,A收到后,发送序号seq=201,确认数据=501,同时ACK=1表示回复,A进入SYN_RECE状态

为什么3次?2次不行吗?
不行,如果是2次握手,A先发一个SYN给B,但是这个SYN因为某些原因没及时到达B,所以A在一定时间后会重发,B会回一个ACK,但是这时候第一个SYN到达了,此时对B来说,这个是一个新的请求,所以会返回ACK,但对A来说,这个SYN是一个无效的请求,并不会处理这个ACK,而B并不知道A不会处理,导致B一直在等待,造成资源浪费。

四次挥手:
三次握手

客户端发送主动请求,FIN=1,seq=u,客户端进入FIN-WAIT-1阶段,服务端收到请求后回复确认报文ACK=1,seq=v,ack=u+1,服务端进入CLOSE-WAIT状态,TCP服务器通知高层的应用进程,此时客户端已经没有进程要发送了。客户端收到信息后就进入FIN-WAIT-2状态;服务端将最后的数据发送完后即向客户端发送链接释放报文,FIN=1,ack=u+1,由于在半关闭状态,服务器很可能发送了一些数据,seq=w,服务器进入LAST-ACk,即最后确认状态。客户端收到请求后,回复ACK=1,ack=w+1,自己的序列号为seq=u+1,客户端进入TIME-WAIT状态,此时TCP链接还没有释放,必须经过2*MSL(最长报文段寿命)的时间后,当客户端撤销相应的TCB后,才进入CLOSED阶段。服务端只要收到客户端发送的确认就立即进入CLOSED状态,撤销TCB,所以服务端比客户端结束的要早。

为什么客户端需要2*MSL才关闭?

作为一个软件开发工程师,我不想去研究这个。大体原因有2个:

1.确定服务端可以收到这个ACK,因为可能会丢失,如果没收到,服务端就会给客户端再发一次,所以客户端等一段时间,如果没收到服务端重发的报文,就说明没有问题。

2.防止类似于“三次握手”中,已经失效的请求连接重新出现在本次连接体系中的情况。客户端发送完最后一个确认报文后,在这个时间里,可以使本次连接中所有的报文都从网络中消失,即耗死它,这样新连接中不会出现旧的连接。

为什么建立连接需要3次握手,断开却需要4次挥手?

这是TCP的半关闭造成的,TCP即然是全双工的,所以每个方向必须单独的进行关闭。建立连接的时候, 服务器在LISTEN状态下,收到建立连接请求的SYN报文后,把ACK和SYN放在一个报文里发送给客户端。

而关闭连接时,服务器收到对方的FIN报文时,仅仅表示对方不再发送数据了但是还能接收数据,而自己也未必全部数据都发送给对方了,所以己方可以立即关闭,也可以发送一些数据给对方后,再发送FIN报文给对方来表示同意现在关闭连接,因此,己方ACK和FIN一般都会分开发送,从而导致多了一次。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C语言是一种广泛使用的编程语言,它具有高效、灵活、可移植性强等特点,被广泛应用于操作系统、嵌入式系统、数据库、编译器等领域的开发。C语言的基本语法包括变量、数据类型、运算符、控制结构(如if语句、循环语句等)、函数、指针等。在编写C程序时,需要注意变量的声明和定义、指针的使用、内存的分配与释放等问题。C语言中常用的数据结构包括: 1. 数组:一种存储同类型数据的结构,可以进行索引访问和修改。 2. 链表:一种存储不同类型数据的结构,每个节点包含数据和指向下一个节点的指针。 3. 栈:一种后进先出(LIFO)的数据结构,可以通过压入(push)和弹出(pop)操作进行数据的存储和取出。 4. 队列:一种先进先出(FIFO)的数据结构,可以通过入队(enqueue)和出队(dequeue)操作进行数据的存储和取出。 5. 树:一种存储具有父子关系的数据结构,可以通过中序遍历、前序遍历和后序遍历等方式进行数据的访问和修改。 6. 图:一种存储具有节点和边关系的数据结构,可以通过广度优先搜索、深度优先搜索等方式进行数据的访问和修改。 这些数据结构在C语言中都有相应的实现方式,可以应用于各种不同的场景。C语言中的各种数据结构都有其优缺点,下面列举一些常见的数据结构的优缺点: 数组: 优点:访问和修改元素的速度非常快,适用于需要频繁读取和修改数据的场合。 缺点:数组的长度是固定的,不适合存储大小不固定的动态数据,另外数组在内存中是连续分配的,当数组较大时可能会导致内存碎片化。 链表: 优点:可以方便地插入和删除元素,适用于需要频繁插入和删除数据的场合。 缺点:访问和修改元素的速度相对较慢,因为需要遍历链表找到指定的节点。 栈: 优点:后进先出(LIFO)的特性使得栈在处理递归和括号匹配等问题时非常方便。 缺点:栈的空间有限,当数据量较大时可能会导致栈溢出。 队列: 优点:先进先出(FIFO)的特性使得

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值