计算机网络_UDP编程流程&TCP和UDP区别

版权声明:私藏源代码是违反人性的罪恶行为!博客转载无需告知,学无止境。 https://blog.csdn.net/qq_41822235/article/details/83961007

一、 流程

1.1 服务器端

int socket(int domain,  int type,  int pro);  //步骤一、生成套接字

int bind(int sockfd,  struct sockaddr* seraddr, int size);  //步骤二、绑定套接字和地址

int recvfrom(int sockfd, void *buff, int size, int flag, //步骤三、将客户端发来的消息读入buf

                   struct sockaddr*cliaddr, int *addrlen);  //用于回复消息, addrlen需要在函数内改变,配合sendto

int sendto(int sockfd, void* buf, int datalen, int flag, //步骤四、服务器向客户端发送消息,形成信息的交互

                   struct sockaddr* cliaddr, int addrlen); //用于发送消息,addrlen是明确的,不会在函数内改变。

int close(int sockfd); //步骤五、关闭套接字

1.2 客户端

int socket(int domain, int type, int pro); //步骤一、 生成套接字

int recvfrom(int sockfd, void *buf, int size, int flag,  //步骤二、接收消息

                   struct sockaddr *cliaddr, int *addrlen);

int sendto(int sockfd, void *buf, int datalen, int flag, //步骤三、发送消息,形成信息的交互

                   struct sockaddr *cliaddr, int addrlen);

int close(int sockfd); //步骤四、关闭套接字

二、 TCP原理 

2.1 字节流服务

图1 TCP工作流程

发送数据的次数和接受数据的次数无关,底层数据发送和接收时,数据有可能会被分开或者合并。 那么如何保证数据是有序的呢?

图2 TCP报头结构

从图2 直观可以看到明确有5行,每行4byte,TCP报头大小至少是20byte;选项是40byte,TCP报头大小∈[20, 60],我们不妨只关注前20byte。 回归主题,到底是如何保证数据是有序的呢?

图3 序号字段示意图

如图3 所示,假设发送的第一个TCP报文的序号是2000,数据量是30byte;那么第二个TCP报文的序号就是2030,以此类推。当接收端收到这4个报文时,接收顺序与发送顺序没有直接关系,虽然是按照1 2 3 4的顺序去发送,但这不能保证会按照1 2 3 4的顺序来接收,接收顺序取决于网络环境等诸多因素,是未知的。但是我把接收到的报文按照SYN从小到大的顺序去读取,就能保证和原发送顺序一致了。 

2.2 接收&发送缓冲区

序号字段一定程度上保证了接收顺序和发送顺序一致,而缓冲区的存在则可以暂时保存数据。TCP协议还有一个神奇之处在于,接收端会检查缓冲区的大小,然后让发送端知道这件事情。发送端见到接收端缓冲区快满了,就会慢点发送数据,见到接收端缓冲区比较空闲,发送数据的数据就快些。

图4 TCP流量控制模型

A、B都是水池:水不管在哪里溢出都是浪费

  • A或B水池将满, 水龙头水量减少;

  • 反之也成立;

 2.3 可靠性评价

  • 前提:所有的数据都能到达对端    <------确认机制和超时重传机制(缓冲区)。
  • 数据不乱序   <------TCP报头中的序号,也可以用于处理重复报文段,如果两个报文序号一致,丢弃一个。
  • 数据不出错   <------16位的校验和字段。

三、 UDP原理

3.1 数据报服务

发送次数和接收次数相等,要么不读取,要么一次将数据读取完,否则UDP报文段数据丢失。必须一次性将整个UDP报文读取完

图5 UDP工作流程

 3.2 可靠性评价

图6 UDP报头结构
  • 前提:所有的数据都能到达对端  <------无法保证:没有发送缓冲区,数据发出去是没有备份的。
  • 数据不乱序 <------无法保证:主要是听天由命,看哪个UDP报文段先到达对端。
  • 数据不出错 <------校验和字段可以保证。

四、 速度比较

4.1 MTU

最大传输单元(Maximum Transmission Unit,MTU)是指一种通信协议的某一层上面所能通过的最大数据包大小(以字节为单位)。最大传输单元这个参数通常与通信接口有关(网络接口卡、串口等)。

4.2 三种时延

图7 时延
  • 发送时延 = 数据块大小/信道带宽。

  • 等待时延:数据排队所经过的延时。

  • 传输时延:信道长度/传输速率 ------客观因素:在技术没有明显提升的前提下,不可改变。

等待时延,就以在银行窗口办理业务来理解吧。假设有一天,我去银行办理业务,来的比较晚;排在了队伍的最后面(把插队的情况排除)。问:什么时候轮到我?这由两个因素决定:1 前面有多少人; 2 具体到每个人办理业务的时间。最极端的情况,我前面虽然只有1个人,但是那个人正在办理一项很重要的业务,耗时较长,能说队伍短我等待的时间一定短吗?再比如说,虽然我前面有5个人,但他们都只办理查询业务(这个是很快的),我排在5个人的队伍后面没准会比排在1个人的队伍后面等待时间更短啊,所以,单凭队伍长短来断定我等待办理业务的时间是不尽合理的。

之所以会提到这个,是为了引出稍后会提到:MTU增加,发送相同数据的包个数减少,也就是队伍长度缩短,能说MTU增加一定能将等待时延降下来吗?不能,因为处理每个包的时间可能会变长,但也只是可能而已。类似于虽然队伍缩短了,但是办理业务的人很磨蹭,等待时间可能并不会减少。

下面再举一个高速公路上运送货物的例子。在这里,货物就是有用的数据:

图8 6车道运送货物示意图

对于单件货物来说,先放在等待队列里,轮到它的时候浪费的时间称为等待时延,假设每辆货车载货量是100单位,但是待发送货物一共701单位,简单理解:第一轮先派出6辆车运送,第二轮派出1辆车运送,从货物准备发送到货物全部发送出去的时间点为止经历的时间称为发送时延,传输时延很好理解,不作类比了。

结合MTU来看看三种时延吧:以太网的MTU值是1500 bytes,假设发送者的协议高层向IP层发送了长度为3008 bytes的数据报文,则该报文在添加20 bytes的IP包头后IP包的总长度是 3028 bytes,因为3028 > 1500,所以该数据报文将被分片,

分片时仅仅对上层的数据进行分片,不需要对原来的IP首部分片,所以要分片的数据长度只有3008,而不是3028。

分片过程如下:

  1. 首先计算最大的IP包中IP净荷的长度 =MTU-IP包头长度=1500-20= 1480 bytes。
  2. 然后把3008 bytes按照1480 bytes的长度分片,将要分为3片,3008= 1480+1480+48。
  3. 最后发送者将为3个分片分别添加IP包头,组成3个IP包后再发送,3个IP包的长度分别为1500、1500、68 bytes。

将MTU和时延结合起来理解一下吧: 

  • MTU越大,传送相同的用户数据所需的数据包个数也越低;
  • 但是MTU增大会增加发送时延,并且MTU越大,数据包中 bit位发生错误的概率也越大。

最终目标是将总时延降下来,所以MTU要选择一个合适的值。

总而言之:UDP是会比TCP快的。

猜你喜欢

转载自blog.csdn.net/qq_41822235/article/details/83961007