认识传输层(UDP与TCP)

2023-10-27

传输层主要负责数据能够从发送端发送到接收端。要正确传输就要明确发送端和接收端,这时候IP地址和端口号一起就可以确定一端了。那么他们是怎么唯一标识的呢?

1 端口号(port)

    端口号唯一标识一个主机上进行通信的不同应用程序。

    在TCP/IP协议中,采用源IP地址、目的IP地址、协议号、源端口号、目的端口号这样一个五元组来进行唯一标识一个通信。

1.1 端口号划分

  • 0~1023:知名端口号,HTTP、FTP、SSH这些广为使用的应用层协议,它们的端口号一般都是固定的
  • 1024~65535:操作系统动态分配的端口号,客户端程序的端口号,都是操作系统从这个范围分配的

1.2 知名端口号

ssh服务器:22端口

ftp服务器:21端口

telnet服务器:23端口

http服务器:80端口

https服务器:443端口

我们还可以使用cat /etc/services 来查看知名端口号:

我们自己在写程序要用到端口号时,要尽量避开这些端口,因为一个端口号不可以绑定多个进程;但反过来,一个进程是可以绑定多个端口号的。上一句说一个端口号不可以绑定多个进程,其实并不准确,应该说一般情况下不可以,但通过fork创建的子进程是和父进程绑定的同一个端口号。

2 UDP协议

2.1 UDP 协议格式

  • 源端口号、目的端口号、UDP长度、校验和都是16位表示
  • UDP长度代表了应用层数据报的最大长度
  • 如果校验和出错,该数据报就会直接丢弃

2.2 UDP的特点

  • 无连接:直到对端的IP地址和端口号就可以进行通信,不需要建立连接
  • 不可靠:没有确认机制,没有重传机制;如果因为网络故障没有发送成功,UDP协议层也不会给应用层发送任何错误信息
  • 面向数据报:应用层交给UDP多长的数据,就发送多长的数据,不会拆分,也不会合并

2.3 UDP缓冲区

  • 严格来说,UDP没有发送缓冲区,调用sendto会将数据直接交给内核,由内核将数据传给网络层协议进行后续的操作
  • UDP具有接受缓冲区,但这个缓冲区不能保证接收的的数据顺序,并且一旦缓冲区满了,后来到达的数据就丢失了

注意:UDP协议的协议头有一个最大长度字段,由16位表示,也就是说,UDP协议发送的最大数据长度是64k。

2.4 基于UDP的应用层协议

  • NFS:网络文件协议
  • TFTP:简单文件传输协议
  • DHCP:动态主机配置协议
  • BOOTP:启动协议(用于无盘设备的启动)
  • DNS:域名解析协议

3 TCP协议

TCP协议全称为传输控制协议,顾明思义,就是要对数据传输的过程做一个详细的控制。

3.1 TCP协议格式

  • 源端口号,目的端口号:表示数据从哪来,到哪去
  • 32位序号和确认序号
  • 4位首部长度:表示TCP报头的长度(有多少个4个字节);TCP头部的最大长度是60
  • 保留的6位是标志位:

URG:紧急指针是否有效

ACK:确认号是否有效

PSH:提示接收端应用程序立刻从TCP缓冲区把数据读走

RST:对方要求重新建立连接;我们把携带RST标识的称为复位报文段

SYN:请求建立连接;我们把携带SYN标识的称为同步报文段

FIN:通知对方,本端要关闭了,我们把携带FIN标识的称为结束报文段

  • 窗口大小:表示了发送方接下来要发送的数据的多少(根据接收方缓冲区的大小决定)
  • 校验和:发送端填充,CRC校验(循环冗余校验);接收端校验若不通过,说明数据有问题
  • 紧急指针

3.2 TCP的连接管理机制

正常情况下,TCP要经过3次握手,4次挥手建立连接。

TCP的三次握手四次挥手

可以点击上面的链接,进行查看。

3.2.1 确认应答(ACK)机制

TCP将每个字节的数据都做了编号,即为序列号。

TCP协议中,接收方陈宫接收到数据后,会回复一个ACK数据包,表示已经确认收到ACK确认号前的所有数据。也就是告诉发送方,我已经收到了哪些数据,下一次从哪里发送。

比如,发送方收到确认序号为1001,表示序号1~1000的数据已经成功接收到,下面要发送的是序号从1001开始的数据。

3.2.2 超时重传机制

        当发送方发送给接收方的数据,接收方没有收到时,就无法发送ACK包,在一定时间后接收方仍旧没有收到ACK,就会重新发送该数据段;

        还有就是,可能是ack丢包,这时候发送方会发送接收方已经接收到的数据,接收方可以通过序号轻松的将重复的数据去掉。

 那么超时时间是如何确定的呢?

最理想的情况下,找一个最小的时间,保证“确认应答可以在这个时间内返回”,但是这个时间的长短随着网络环境的不同是有差异的,如果重传时间太长,会影响整体的传送效率;如果时间太短,会导致频繁的发送同样的数据。

TCP为了保证在任何情况下都可以高性能的发送数据,会动态计算最大超时时间。


  • Linux中,超时以500ms为单位进行控制,每次判定超时重传的时间为500ms的整数倍
  • 如果重发一次后还得不到应答,下一次等待2*500ms后再次重传
  • 如果仍然得不到应答, 等待 4*500ms 进⾏重传. 依次类推, 以指数形式递增
  • 重传次数累计到一定的数字,TCP会认为网络或对端主机出现异常,强制关闭连接

3.2.3 滑动窗口

上面我们讲利用确认应答以及重传机制可以可靠地进行数据传输,但是这样我们每次要发送一段数据都要等待上一个数据发送成功并返回了ACK之后才能发送,这样的效率未免太慢。这时候就可以选择一次发送多组数据:

在上面的图中,一次可以发送4000个字节的数据,当发送端收到第一个ACK时,滑动窗口向后滑动,4001~5000的数据才可以发送,如下图所示:

发送前四个段时,不需要等待可以同时发送,当收到第一个ACK时,滑动窗口向后滑动,第五段的数据才可以进行发送。操作系统为了维护这个滑动窗口,开辟了发送缓冲区,来记录有哪些数据没有收到应答;只有收到应答的数据才可以从缓冲区删除。滑动窗口越大,网络吞吐率越高。


丢包情况一:ACK丢了

当数据包成功让接收方接收到,接收方发送的ACK丢失的情况下,后续数据的ACK包可以确认。


丢包情况二:数据包丢了

当某一段报文丢失后,比如1001~2000数据丢失,接收方会不停发送1001ack来提醒发送方“我需要的9数据是1001”。当发送方连续收到3次该应答,发送方就会重新发送该数据报。

这种机制也叫“快重传”机制


3.2.4 流量控制

接收端处理数据的能力有限,如果发送端发送数据太快,导致接收端缓冲区满了,这时候如果发送方继续发送数据,就有可能造成丢包。

因此TCP支持根据接收端的处理能力,来决定发送端的发送速度,这个机制叫做流量控制

如上图所示,接收端将自己可以接收的缓冲区大小放入TCP首部中的“窗口大小”字段,通过ACK通知发送端;接收端一旦发现自己的缓冲区快满了,就会将窗口大小设置成一个更小的值发送给发送方;发送端接收到这个字段,就会减慢自己的发送速度;如果接受缓冲区满了,就会将窗口值置为0;这时候发送方就不再发送数据,但是需要定时发送一个窗口探测数据段,使接收端把窗口大小告诉发送端。

我们知道,TCP首部中的窗口大小字段由16位表示,最大表示65535,那么TCP窗口最大就是65535字节么?

实际上,TCP首部中还包含了一个窗口扩大因子M,实际窗口大小是窗口字段值左移M位。

3.2.5 慢启动和拥塞控制

虽然有了滑动窗口可以帮助数据进行可靠传输,可是不止接收端的处理能力还有网络状况可能对数据的可靠传输造成影响,如果网络状况不好,一下子发送大量的数据,可能会造成丢包。

TCP引入慢启动,先发送少量的数据,摸清网络的拥堵状况,在决定按照多大的速度传输数据。

慢开始算法:

慢开始门限的初始值设置为 16 个报文段,即 ssthresh = 16

发送端的发送窗口不能超过拥塞窗口 cwnd 和接收端窗口 rwnd 中的最小值。我们假定接收端窗口足够大,因此现在发送窗口的数值等于拥塞窗口的数值。

在执行慢开始算法时,拥塞窗口 cwnd 的初始值为 1,发送第一个报文段 M0。

发送端收到 ACK1 (确认 M0,期望收到 M1)后,将 cwnd 从 1 增大到 2,于是发送端可以接着发送 M1 和 M2 两个报文段。

接收端发回 ACK2 和 ACK3。发送端每收到一个对新报文段的确认 ACK,就把发送端的拥塞窗口加 1。现在发送端的 cwnd 从 2 增大到 4,并可发送 M3 ~ M6共 4个报文段

发送端每收到一个对新报文段的确认 ACK,就把发送端的拥塞窗口加 1,因此拥塞窗口 cwnd 随着传输次数按指数规律增长。

拥塞控制算法:

拥塞窗口 cwnd 增长到慢开始门限值 ssthresh 时(即当 cwnd = 16 时),就改为执行拥塞避免算法,拥塞窗口按线性规律增长。

假定拥塞窗口的数值增长到 24 时,网络出现超时(表明网络拥塞了)。

更新后的 ssthresh 值变为 12(即发送窗口数值 24 的一半),拥塞窗口再重新设置为 1,并执行慢开始算法。

当 cwnd = 12 时改为执行拥塞避免算法,拥塞窗口按按线性规律增长,每经过一个往返时延就增加一个 MSS 的大小。

少量丢包,仅仅触发超时重传;大量丢包,认为网络拥塞。

3.2.6 延迟应答

如果当接收方收到数据就立刻应答,比如接收缓冲区是1M大小,接受了500k的数据,那么返回的窗口大小就是500k;但是接收方的处理数据的速度可能很快,如果延迟200ms的时间在进行应答,返回的窗口大小就是1M,这样网络吞吐率就会大大提高。这就是延迟应答。延迟应答的目的就是为了提高传输效率。

那么,所有的包都可以延迟应答么?不是,

数量限制:每隔N个包就要应答一次;

时间限制:超过最大延迟时间就应答一次;

不同的操作系统的N和最大延迟时间不同,一般情况下,N取2,最大延迟时间为200ms。

3.2.7 捎带应答

在延迟应答的基础上, 我们发现, 很多情况下, 客户端服务器在应⽤层也是 "⼀发⼀收" 的. 意味着客户端给服务器说了 "How are you", 服务器也会给客户端回⼀个 "Fine, thank you";那么这个时候ACK就可以搭顺⻛⻋, 和服务器回应的 "Fine, thank you" ⼀起回给客户端。
 

3.2.8 面向字节流

创建⼀个TCP的socket, 同时在内核中创建⼀个 发送缓冲区 和⼀个 接收缓冲区;

  • 调⽤write时, 数据会先写⼊发送缓冲区中;
  • 如果发送的字节数太⻓, 会被拆分成多个TCP的数据包发出;
  • 如果发送的字节数太短, 就会先在缓冲区⾥等待, 等到缓冲区⻓度差不多了, 或者其他合适的时机发送出去;
  • 接收数据的时候, 数据也是从网卡驱动程序到达内核的接收缓冲区;然后应⽤程序可以调⽤read从接收缓冲区拿数据;
  • 另⼀⽅⾯, TCP的⼀个连接, 既有发送缓冲区, 也有接收缓冲区, 那么对于这⼀个连接, 既可以读数据,也可以写数据. 这个概念叫做 全双⼯

由于缓冲区的存在, TCP程序的读和写不需要⼀⼀匹配, 例如:

  • 写100个字节数据时, 可以调⽤⼀次write写100个字节, 也可以调⽤100次write, 每次写⼀个字节;
  • 读100个字节数据时, 也完全不需要考虑写的时候是怎么写的, 既可以⼀次read 100个字节, 也可以⼀次read⼀个字节, 重复100次;

3.2.9 粘包问题

首先,明确粘包问题中的“包”,指的是应用层的数据包。在TCP协议中,没有如同UDP一样的“报文长度”的字段,但是有一个序号的字段,站在传输层的角度,数据是一个个报文过来,按照序号排好的数据放在缓冲区中;但是在应用层的角度,只看到了一连串的字节数据,并不知道一个报文的开始和结束。这时候,如果上一个没读完,下一个发送了新的数据,要读的时候,就可能读到前面没读完的数据,对该进程来说是错误的数据。这就是粘包问题

那么,如何避免呢?


  • 对于定⻓的包, 保证每次都按固定⼤⼩读取即可;
  • 对于变⻓的包, 可以在包头的位置, 约定⼀个包总⻓度的字段, 从⽽就知道了包的结束位置;
  • 对于变⻓的包, 还可以在包和包之间使⽤明确的分隔符(应⽤层协议, 是程序猿⾃⼰来定的, 只要保证分隔符不和正⽂冲突即可);

4 TCP/UDP对比

  • TCP用于可靠传输的情况,应用于文件传输,重要状态更新等场景
  • UDP用于高速传输和实时性要求较高的通信领域;另外,UDP可以用于广播。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

认识传输层(UDP与TCP) 的相关文章

  • valgrind:内存泄漏的检查工具

    valgrind 是帮助程序员寻找程序里的 bug 和改进程序性能的工具集 擅长发现内存的管理问题 里面有若干工具 其中最重要的是 memcheck 工具 用于检查内存的泄漏 memcheck 能发现如下的问题 使用未初始化的内存 使用已经
  • 【手把手教你写服务器】客户端程序和服务器程序的简单实现

    文章目录 1 基本TCP客户 服务器程序的套接字函数 2 server c 3 client c 1 基本TCP客户 服务器程序的套接字函数 下图中各个函数的功能 参数及返回值自行查阅 UNIX网络编程卷1 套接字联网API 第4章 2 s
  • pthread_cond_broadcast 使用

    使用pthread cond signal只能唤醒N个线程中的一个 而pthread cond broadcast可以唤醒全部的N个线程 实例 include
  • 网络编程之本地套接字和网络套接字比较与本地套接字通信案例01

    1 socket IPC 本地套接字domain 1 1 本地通信的方法 1 pipe mkfifo 两者实现最简单 2 mmap 非血缘关系进程间 3 信号 开销小 4 domain 稳定性最好 注意 在本节domain称之为本地套接字
  • 网络编程之udp学习之udp的多播(组播)和广播案例03

    概述 关于多播 广播这些我Qt相关的文章 也有讲述过 https blog csdn net weixin 44517656 article details 105950817 ip相关知识 https blog csdn net weix
  • 06libevent下通信中bufferevent缓冲区的特性介绍

    06libevent下通信中bufferevent缓冲区的特性介绍 以下是关于libevent学习的相关文章 01libevent库的下载与安装并且测试是否安装成功 02libevent库的整体框架思想 03libevent下通信的主要函数
  • Posix信号量

    Posix信号量 一 Posix信号量 1 概述 二 Posix提供两种信号量 有名信号量和基于内存的信号量 三 命名信号量 1 sem open和sem close函数 2 sem unlink函数 3 sem wait函数 5 sem
  • epoll实现原理

    epoll的使用 epoll只有以下的三个系统函数调用 epoll create epoll ctl和epoll wait int epoll create int size 其中参数 1 size指明了生成描述符的最大范围 该函数返回一个
  • linux网络编程(一)

    1 linux的网络模型 linux使用的网络模型是TCP UP四层网络模型 主要由应用程序 传输层 网络层 网络接口层组成 与OSI七层模型不同 但是又相互对应 它们之间关系如下图 OSI模型的应用层 表示层 会话层对应着TCP IP模型
  • Linux网络编程socket错误分析

    转自 http aigo iteye com blog 1911134 socket错误码 EINTR 4 阻塞的操作被取消阻塞的调用打断 如设置了发送接收超时 就会遇到这种错误 只能针对阻塞模式的socket 读 写阻塞的socket时
  • moudo网络库剖析

    muduo简介 muduo是陈硕大神在Linux平台下基于C C 开发的高性能网络库 在此基础上可以很方便的扩展 进行二次开发编写如http服务器 muduo网络库的核心框架 one thread per thread Reactor模式
  • 设置可执行程序的名称

    argc 命令行参数的个数 argv 是个数组 每个数组元素都是指向一个字符串的 char 里边存储的内容是所有命令行参数 argv 内存之后接着就是连续的环境变量参数信息内存 里边存储的内容是可执行程序执行时有关的所有环境变量参数信息 可
  • 关于socket的各种错误码

    1 INVALID SOCKET 表示该 socket fd 无效 如 accept 2 或 socket 2 等在创建socketfd时 int m socket socket AF INET SOCK STREAM 0 if m soc
  • 抓包工具Wireshark使用体会

    这两天在工作上遇到了一些问题 必须要用抓包工具来捕获手机端发送过来的数据包 分析其帧结构 以前虽然学习过网络知识 但是也从未接触过抓包工具Wireshark 迫于工作的压力 自己在摸索中学到了一些基本的使用方法 文件格式 pcap 帧排序
  • unix域套接字

    UNIX域套接字被用来和同一机器上运行的进程通信 尽管因特网域套接字可以用作同样的目的 然而UNIX域套接字更高效 UNIX域套接字只拷贝 数据 它们没有要执行的协议处理 没有要增加或删除的网络头 没有要计算的校验和 没有要产生的序列号 没
  • 关于AF_INET和PF_INET

    AF 表示ADDRESS FAMILY 地址族 PF 表示PROTOCL FAMILY 协议族 Winsock2 h中 define AF INET 0 define PF INET AF INET 所以在windows中AF INET与P
  • 分配给套接字的IP地址与端口号

    文章目录 1 网络地址 Internet Address 2 网络地址分类与主机地址边界 3 用于区分套接字的端口号 IP 是 Internet Protocol 网络协议 的简写 是为收发网络数据而分配给计算机的值 端口号并非赋予计算机的
  • SOCK_RAW PF_PACKET IPv6带物理地址发送报文

    通过link layer发送IPv4 IPv6 例子如下 http www pdbuchan com rawsock rawsock html 发送ipv4 http www pdbuchan com rawsock tcp4 ll c 发
  • Linux环境下,安装libevent库

    前言 最近在进行网络编程的学习 在安装libevent库时 遇到了各种各样的问题 最后通过一条条的去搜索问题关键字 费尽千辛万苦 终于完成了安装 也能够成功的运行起来其中所提供的案例代码 所以在这里将各种零碎的问题以及解决方案整理一下 帮助
  • TCP发送数据流程详解

    B S通信简述 整个计算机网络的实现体现为协议的实现 TCP IP协议是Internet的核心协议 HTTP协议是比TCP更高层次的应用层协议 HTTP HyperText Transfer Protocol 超文本传输协议 是互联网上应用

随机推荐