当前位置:   article > 正文

TCP/UDP入门与实例详解_tcp与udp例子

tcp与udp例子

TCP简介

传输层控制协议(Transport Control Protocol),TCP/IP协议栈的核心之一。位于应用层与网络层之间,提供面向连接的、可靠的字节流服务。

记住关键词“面向连接”、“可靠”、“字节流”,这是学习掌握TCP的关键:

  • 面向连接:客户端、服务端交换数据前,需要建立连接;
  • 可靠:通过特定机制,在不可靠的网络之上,确保报文准确送达,
  • 字节流:数据的最小单位为字节。至于字节中存储内容的含义,由于应用层的程序决定。

 

TCP如何确保服务可靠性

  • 应用数据切割:应用数据被分隔成TCP认为最适合发送的多个报文段(由特定的算法和机制来确认)
  • 接收端确认:接收端收到报文段后,会向发送端发送确认报文;
  • 超时重传机制:发送端发送一个报文段后,会启动定时器,等待接收端确认收到这个报文;如果没有及时收到确认,发送端会重新发送报文;
  • 数据校验和:发送端发送的报文首部中,有个叫做校验和(checksum)的特殊字段,它是根据报文的首部、数据计算出来的。这是一个端到端的校验和,用来检测传输过程数据的变化。接收端收到报文后会对校验和进行检查,如果校验和存在差错,则丢弃这个报文,且不确认收到此报文(等待发送端超时重发)
  • 报文段排序:TCP报文包裹在IP数据包里进行传输,而IP数据包的到达次序是不固定的。接收端会对接收到的报文段重新排序,这个对应用层是无感知的;
  • 去重复:接收端丢弃重复的报文(比如,因某些原因,虽然接收端已经收到报文,且给发送端发送了接收确认,但接收端没有收到该确认,超时后重新发送了同样的报文);
  • 流量控制:TCP连接双方都有固定大小的缓冲空间,且只允许发送端发送缓冲空间能够容纳的数据,避免缓冲区溢出;

TCP传输服务的可靠性对应用层的开发者来说至关重要。作为应用层的开发者(比如HTTP server),除了业务逻辑之外,如果还需要操心数据是否正常送达,接收到的数据是否完整,开发效率会相当低下。

 

TCP首部格式

TCP首部格式如下图所示,在不包含可选字段的情况下,大小通常为20个字节。部分字段定义可能并不直观,如果读者觉得某些首部字段不好理解,建议先跳过,结合后文的实例可能更容易理解些。

比如 Sequence Number/Acknowledgment Number/ACK/SYN,结合TCP建立连接的过程来看,会更好理解。

Source Port(来源端口):16位

Destination Port(目的端口):16位

Sequence Number(序号):32位

TCP报文段中的数据部分,每一个字节都有它的序号(递增)。根据控制标志(Control Bits)中的SYN是否为1,Sequence Number 表达不同的含义:

  • SYN = 1:当前为连接建立阶段,此时的序号为初始序号(ISN)。当数据传输正式开始时,数据的第一个字节的序号为 ISN + 1;
  • SYN = 0:当前报文段中,数据部分的第一个字节的序号。

Acknowledgment Number(确认序号):32位

当控制标志的ACK为1时,表示发送方希望收到的下一个报文段的序号(Sequence Number)。一旦连接建立成功,ACK值一直为1。

Data Offset(数据偏移量):4位

TCP报文段的首部长度,单位是word(4字节)。字面含义是:TCP报文段的数据的起始处,距离TCP报文段的起始处 的偏移量。4个字节最大能表示的数字是15,所以首部最大60字节。

Reserved(保留字段):6位

预留作为后续用途,必须是0。

Control Bits(控制标志):6位

一共有6个控制标志,其中SYN/ACK、FIN/ACK主要用于连接的建立、断开阶段。

  • URG: 当置为1时,表示紧急指针(Urgent Pointer)字段有效;
  • ACK: 确认序号字段(Acknowledgment Number)有效;
  • PSH: 接收方应立即把这个报文段交给应用层;
  • RST: 重建连接;
  • SYN: 同步序号,用于建立连接;
  • FIN: 发送端不再发送数据;

Window Size(窗口大小):16位

允许对方发送的数据量。告诉对方自己缓冲区还能容纳多少字节,用来控制对方发送数据的速度。

比如,服务端发送给客户端的TCP报文段中,确认序号是701,窗口字段(Window Size)是1000,表明服务端能够接受客户端发来的,序号从701开始的1000字节数据。

Checksum(校验和):16位

发送端对TCP首部、数据进行CRC运算得出的结果。接收端收到数据后,对接收到的TCP报文段的首部、数据进行CRC运算,并跟TCP首部中的校验和进行对比,确保数据在传输过程中没有损坏。

计算、校验规则这里先不展开。

Urgent Pointer(紧急指针):16位

仅在URG=1时才生效,它的值是一个偏移量,和序号字段中的值相加得到紧急数据最后一个字节的序号。

options(可选字段):大小不固定

最常见的可选字段是MSS(Maximum Segment Size),表示最长报文大小,通信双方通常在连接的第一个报文段中指明这个选项。(只能出现在SYN报文中)

 

建立连接 vs 断开连接

TCP的两段正式开始传输数据前,需要先建立连接。一旦数据传输完成,则需要断开连接。

后面章节中,会通过实际例子说明TCP数据传输的完整生命流程。在这之前,先简单介绍下TCP是如何建立连接以及断开连接的,也就是我们所熟悉的3次握手以及4次挥手。

这里留几个问题:

  1. 建立连接的主要目的是什么?做了哪些事情?
  2. 建立连接为什么是3次握手,可不可以是2次?
  3. 断开连接一定要4次挥手吗?

Seq => Sequence Number,Ack => Acknowledgment Number,[SYN] => 控制标志SYN,[ACK] => 控制标志ACK

 

建立连接

一般情况下,握手流程如 下图 所示,主要做了两件事情:

  1. 互相确认对方当前可以建立连接
  2. 互相交换确认初始序列号(ISN)

 

三次握手过程:

  1. 主动方A发送一个FIN(终止信号)给被动方B,表示要终结主动方A到被动方B的连接;
  2. 被动方B收到了FIN信号,返回ACK信号给主动方,表示从主动方到被动方的连接关闭了,也就是主动方不能再发送数据给被动方。
  3. 被动方B在发送完数据后,给主动方A发送一个FIN信号,请求要终结被动方B到主动方A的连接;

 

断开连接

一般情况下,TCP断开连接需要4次挥手。假设 TCP A 主动断开连接,流程如下。主要就是告知对方,自己准备断开连接了,并且等待对方的确认。

四次挥手过程:

1.主动方发送Fin+Ack报文,并置发送序号为X;

2.被动方发送Ack报文,并置发送序号为Z,确认序号为X+1;

3.被动方发送Fin+Ack报文,并置发送序号为Y,再确认序号为X

4.主动方A收到了FIN信号,返回ACK序号Y给被动方B,表示从被动方B到主动方A的连接关闭了,也就是被动方不能再发送数据给主动方

 

从实例看TCP生命周期

在这一小节,会通过例子,阐述TCP从建立连接,到数据传输,到最后断开连接的整个过程,并通过wireshark抓包探究一些通信的细节。

首先,打开wireshark监听网络请求。然后,在终端输入如下命令发送HTTP请求。

curl http://id.qq.com/index.html

下面为wireshark抓包截图,分为3个部分,分别为 (1)建立连接,(2)数据传输,(3)断开连接。

tcp请求

建立连接

1、本地 -> 服务端:[SYN] Seq=0;

备注:本例子中中,客户端、服务端的初始Seq值其实不是0,截图中展示的0是个相对值,是wireshark为了方便开发者进行抓包分析转化过来的。

2、服务端 -> 本地:[SYN, ACK] Seq=0, Ack=1;

3、本地 -> 服务端:[ACK] Seq=1, Ack=1

到这里,双方连接建立,开始交换数据

数据传输

数据交换是双向的,这里以服务端的HTTP响应为例子。响应内容较大,被拆成了多个TCP包。整个数据发送的过程,就是服务端向客户端发送数据,客户端向服务端发送确认的过程。

1.1、服务端->客户端:Seq=1,TCP数据长度273。也就是说,服务端发送的报文段中,第一个数据字节的序号是1;下一个TCP报文段,第一个数据字节的序号应该是274。

1.2、客户端->服务端:Ack=274。表示客户端已经收到序号274之前的所有字节;也就是说,服务端如果继续给客户端发送TCP报文,应该发送序号274及以后的数据。

2.1、服务端->客户端:Seq=274,TCP数据长度1400。也就是说,服务端发送的报文段中,第一个数据字节的序号是274;下一个TCP报文段,第一个数据字节的序号应该是1674(274 + 1400)。

断开连接

从抓包中看到比较有意思的点。当服务端收到客户端的断开请求时(FIN=1),服务端在同一个响应包里发送了FIN、ACK,达到了减少一个数据包的效果。

 

UDP详解

我们来看一下 UDP 的包头:
UDP 包头
由上图可以看出,UDP 除了端口号,基本啥都没有了。如果没有这两个端口号,数据就不知道该发给哪个应用。

 

UDP的主要概念

UDP不提供复杂的控制机制,利用IP提供面向无连接的通信服务。并且它是将应用程序发来的数据在收到的那一刻,立刻按照原样发送到网络上的一种机制。即使是出现网络拥堵的情况下,UDP也无法进行流量控制等避免网络拥塞的行为。

此外,传输途中如果出现了丢包,UDP也不负责重发。甚至当出现包的到达顺序乱掉时也没有纠正的功能。如果需要这些细节控制,那么不得不交给由采用UDP的应用程序去处理。

换句话说,UDP将部分控制转移到应用程序去处理,自己却只提供作为传输层协议的最基本功能。UDP有点类似于用户说什么听什么的机制,但是需要用户充分考虑好上层协议类型并制作相应的应用程序。

 

基于 UDP 的几个例子

1.直播。直播对实时性的要求比较高,宁可丢包,也不要卡顿的,所以很多直播应用都基于 UDP 实现了自己的视频传输协议。
2.实时游戏。游戏的特点也是实时性比较高,在这种情况下,采用自定义的可靠的 UDP 协议,自定义重传策略,能够把产生的延迟降到最低,减少网络问题对游戏造成的影响
3.物联网。一方面,物联网领域中断资源少,很可能知识个很小的嵌入式系统,而维护 TCP 协议的代价太大了;另一方面,物联网对实时性的要求也特别高。比如 Google 旗下的 Nest 简历 Thread Group,推出了物联网通信协议 Thread,就是基于 UDP 协议的

UDP应用场景:
  1.面向数据报方式
  2.网络数据大多为短消息 
  3.拥有大量Client
  4.对数据安全性无特殊要求
  5.网络负担非常重,但对响应速度要求高
 

TCP与UDP基本区别


  1.基于连接与无连接
  2.TCP要求系统资源较多,UDP较少; 
  3.UDP程序结构较简单 
  4.流模式(TCP)与数据报模式(UDP); 
  5.TCP保证数据正确性,UDP可能丢包 
  6.TCP保证数据顺序,UDP不保证 
  
 

参考文献:

程序员小卡:https://www.cnblogs.com/chyingp/p/understanding-tcp.html

urnothd:https://blog.csdn.net/languolan/article/details/81357226

Object object:https://blog.csdn.net/zhang6223284/article/details/81414149#1_UDP_12

Li_Ning_: https://blog.csdn.net/li_ning_/article/details/52117463

https://baike.baidu.com/item/SYN/8880122?fr=aladdin 

 

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/588837
推荐阅读
相关标签
  

闽ICP备14008679号