2023年7月23日发(作者:)
Linux⽹络协议栈TCP与UDP区别区别⼀、是否基于连接TCP是⾯向连接的协议,⽽UDP是⽆连接的协议。即TCP⾯向连接;UDP是⽆连接的,即发送数据之前不需要建⽴连接。区别⼆、可靠性 和 有序性 区别TCP 提供交付保证(Tcp通过校验和,重传控制,序号标识,滑动窗⼝、确认应答实现可靠传输),⽆差错,不丢失,不重复,且按序到达,也保证了消息的有序性。该消息将以从服务器端发出的同样的顺序发送到客户端,尽管这些消息到⽹络的另⼀端时可能是⽆序的。TCP协议将会为你排好序。UDP不提供任何有序性或序列性的保证。UDP尽最⼤努⼒交付,数据包将以任何可能的顺序到达。TCP的逻辑通信信道是全双⼯的可靠信道,UDP则是不可靠信道区别三、实时性UDP具有较好的实时性,⼯作效率⽐TCP⾼,适⽤于对⾼速传输和实时性有较⾼的通信或⼴播通信。区别四、协议⾸部⼤⼩TCP⾸部开销20字节; UDP的⾸部开销⼩,只有8个字节 。区别五、运⾏速度TCP速度⽐较慢,⽽UDP速度⽐较快,因为TCP必须创建连接,以保证消息的可靠交付和有序性,毕竟TCP协议⽐UDP复杂。区别六、拥塞机制UDP没有拥塞控制,因此⽹络出现拥塞不会使源主机的发送速率降低(对实时应⽤很有⽤,如IP电话,实时视频会议等)区别七、流模式(TCP)与数据报模式(UDP);TCP⾯向字节流,实际上是TCP把数据看成⼀连串⽆结构的字节流;UDP是⾯向报⽂的 。区别⼋、资源占⽤TCP对系统资源要求较多,UDP对系统资源要求较少。TCP被认为是重量级的协议,⽽与之相⽐,UDP协议则是⼀个轻量级的协议。因为UDP传输的信息中不承担任何间接创造连接,保证交货或秩序的的信息。这也反映在⽤于承载元数据的头的⼤⼩。区别九、应⽤每⼀条TCP连接只能是点到点的;UDP⽀持⼀对⼀,⼀对多,多对⼀和多对多的交互通信 。基于UDP不需要建⽴连接,所以且适合多播的环境,UDP是⼤量使⽤在游戏和娱乐场所。TCP与UDP应⽤场景TCP应⽤场景:效率要求相对低,但对准确性要求相对⾼的场景。因为传输中需要对数据确认、重发、排序等操作,相⽐之下效率没有UDP⾼。举⼏个例⼦:⽂件传输(准确⾼要求⾼、但是速度可以相对慢)、接受邮件、远程登录。UDP应⽤场景:效率要求相对⾼,对准确性要求相对低的场景。举⼏个例⼦:QQ聊天、在线视频、⽹络语⾳电话(即时通讯,速度要求⾼,但是出现偶尔断续不是太⼤问题,并且此处完全不可以使⽤重发机制)、⼴播通信(⼴播、多播)。杂记1. UDP/TCP检验和是把⾸部和数据部分⼀起都校验(⽽IP层只检验数据报⾸部)2. UDP对应⽤层传下来的报⽂既不合并也不拆分,直接加8个字节的头部就直接转发给IP层(⽽TCP就不⼀样)3. MSS是TCP数据字段的报⽂长度:数据字段最⼤长度(TCP也是⾸部固定部分是20个字节,最长是60个字节)4. TCP拥塞控制过程:(通过控制发送窗⼝的⼤⼩)慢开始:每次⼆倍增长,直到慢开始的门限值拥塞避免:每次增加⼀个字节,直到发⽣超时重传快重传:当收到连续三个重复确认快恢复:窗⼝和门限值都变为⼀半,然后开始拥塞避免,重复…5. Linux的tcp抓包命令tcpdump6. IP数据报整个最⼤是1500个字节(IP⾃⼰的⾸部固定部分是20个字节,最长是60个字节)内核常见⽂件⽹络信息传输过程发送端应⽤层socketLinux系统中,socket 属于⽂件系统的⼀部分,⽹络通信可以被看作是对⽂件的读取,使得我们对⽹络的控制和对⽂件的控制⼀样⽅便。UDP的socket处理过程:TCP的socket处理过程:应⽤层处理流程1. ⽹络应⽤调⽤Socket API socket (int family, int type, int protocol) 创建⼀个 socket,该调⽤最终会调⽤ Linux system callsocket() ,并最终调⽤ Linux Kernel 的 sock_create() ⽅法。2. 该⽅法返回被创建好了的那个 socket 的 file descriptor。3. 对于每⼀个 userspace ⽹络应⽤创建的 socket,在内核中都有⼀个对应的 struct socket和 struct sock。其中,struct sock 有三个队列(queue),分别是 rx (接受), tx(发送) 和 err(错误),在 sock 结构被初始化的时候,这些缓冲队列也被初始化完成;在收据收发过程中,每个 queue 中保存要发送或者接受的每个 packet对应的 Linux ⽹络栈 sk_buffer 数据结构的实例 skb。(sk_buff(socket buffer)结构是linux⽹络代码中重要的数据结构,它管理和控制接收或发送数据包的信息。)4. 对于 TCP socket 来说,应⽤调⽤ connect()API ,使得客户端和服务器端通过该 socket 建⽴⼀个虚拟连接。在此过程中,TCP协议栈通过三次握⼿会建⽴ TCP 连接。默认地,该 API 会等到 TCP 握⼿完成连接建⽴后才返回。在建⽴连接的过程中的⼀个重要步骤是,确定双⽅使⽤的 Maxium Segemet Size (MSS)。5. 因为 UDP 是⾯向⽆连接的协议,因此它是不需要该步骤的。6. 应⽤调⽤ Linux Socket 的 send 或者 write API 来发出⼀个 message 给接收端sock_sendmsg 被调⽤,它使⽤ socket descriptor 获取 sock struct,创建 message header 和 socket control message7. _sock_sendmsg 被调⽤,根据 socket 的协议类型,调⽤相应协议的发送函数。对于 TCP ,调⽤ tcp_sendmsg() 函数。对于 UDP 来说,userspace 应⽤可以调⽤ send()/sendto()/sendmsg() 三个 system call 中的任意⼀个来发送 UDP message,它们最终都会调⽤内核中的 udp_sendmsg() 函数。传输层传输层的最终⽬的是向它的⽤户提供⾼效的、可靠的和成本有效的数据传输服务,主要功能包括 :(1)构造 TCP segment(2)计算 checksum(3)发送回复(ACK)包(4)滑动窗⼝(sliding windown)等保证可靠性的操作。TCP 协议栈的⼤致处理过程如下图所⽰:TCP 栈简要过程:1. tcp_sendmsg 函数会⾸先检查已经建⽴的 TCP connection 的状态,然后获取该连接的 MSS,开始 segement 发送流程。2. 构造 TCP 段的 playload:它在内核空间中创建该 packet 的 sk_buffer 数据结构的实例 skb,从 userspace buffer 中拷贝packet 的数据到 skb 的 buffer。3. 构造 TCP header。4. 计算 TCP 校验和(checksum)和 顺序号 (sequence number)。5. TCP 校验和是⼀个端到端的校验和,由发送端计算,然后由接收端验证。其⽬的是为了发现TCP⾸部和数据在发送端到接收端之间发⽣的任何改动。如果接收⽅检测到校验和有差错,则TCP段会被直接丢弃。TCP校验和覆盖 TCP ⾸部和 TCP 数据。6. 发到 IP 层处理:调⽤ IP handler 句柄 ip_queue_xmit,将 skb 传⼊ IP 处理流程。UDP 栈简要过程:1. UDP 将 message 封装成 UDP 数据报2. 调⽤ ip_append_data() ⽅法将 packet 送到 IP 层进⾏处理。IP ⽹络层 - 添加header 和 checksum,路由处理,IP fragmentation⽹络层的任务就是选择合适的⽹间路由和交换结点, 确保数据及时传送。⽹络层将数据链路层提供的帧组成数据包,包中封装有⽹络层包头,其中含有逻辑地址信息- -源站点和⽬的站点地址的⽹络地址。其主要任务包括(1)路由处理,即选择下⼀跳(2)添加 IP header(3)计算 IP header checksum,⽤于检测 IP 报⽂头部在传播过程中是否出错(4)可能的话,进⾏ IP 分⽚(5)处理完毕,获取下⼀跳的 MAC 地址,设置链路层报⽂头,然后转⼊链路层处理。接收端传输层 (TCP/UDP)1. 传输层 TCP 处理⼊⼝在 tcp_v4_rcv 函数(位于 linux/net/ipv4/tcp ipv4.c ⽂件中),它会做 TCP header 检查等处理。2. 调⽤ _tcp_v4_lookup,查找该 package 的 open socket。如果找不到,该 package 会被丢弃。3. 接下来检查 socket 和 connection 的状态。4. 如果socket 和 connection ⼀切正常,调⽤ tcp_prequeue 使 package 从内核进⼊ user space,放进 socket 的 receivequeue。然后 socket 会被唤醒,调⽤ system call,并最终调⽤ tcp_recvmsg 函数去从 socket recieve queue 中获取segment。接收端 - 应⽤层1. 每当⽤户应⽤调⽤ read 或者 recvfrom 时,该调⽤会被映射为/net/socket.c 中的 sys_recv 系统调⽤,并被转化为sys_recvfrom 调⽤,然后调⽤ sock_recgmsg 函数。2. 对于 INET 类型的 socket,/net/ipv4/af inet.c 中的 inet_recvmsg ⽅法会被调⽤,它会调⽤相关协议的数据接收⽅法。3. 对 TCP 来说,调⽤ tcp_recvmsg。该函数从 socket buffer 中拷贝数据到 user buffer。4. 对 UDP 来说,从 user space 中可以调⽤三个 system call recv()/recvfrom()/recvmsg() 中的任意⼀个来接收 UDP package,这些系统调⽤最终都会调⽤内核中的 udp_recvmsg ⽅法。sk_buff 是什么当⽹络包被内核处理时,底层协议的数据被传送更⾼层,当数据传送时过程反过来。由不同协议产⽣的数据(包括头和负载)不断往下层传递直到它们最终被发送。因为这些操作的速度对于⽹络层的表现⾄关重要,内核使⽤⼀个特定的结构叫 sk_buff, 其定义⽂件在skbuffer.h。Socket buffer被⽤来在⽹络实现层交换数据⽽不⽤拷贝来获取数据包 –这显著获得速度收益。sk_buff 是 Linux ⽹络的⼀个核⼼数据结构,其定义⽂件在 skbuffer.h。socket kernel buffer (skb) 是 Linux 内核⽹络栈(L2 到 L4)处理⽹络包(packets)所使⽤的 buffer,它的类型是 sk_buffer。简单来说,⼀个 skb 表⽰ Linux ⽹络栈中的⼀个 packet;TCP 分段和 IP 分组⽣产的多个 skb 被⼀个 skb list 形式来保存。struct sock 有三个 skb 队列(sk_buffer queue),分别是 rx , tx 和 err。struct sk_buff { /* These two members must be first. */ # packet 可以存在于 list 或者 queue 中,这两个成员⽤于链表处理 struct sk_buff *next; struct sk_buff *prev; struct sk_buff_head *list; #该 packet 所在的 list ... struct sock *sk; #跟该 skb 相关联的 socket struct timeval stamp; # packet 发送或者接收的时间,主要⽤于 packet sniffers struct net_device *dev; #这三个成员跟踪该 packet 相关的 devices,⽐如接收它的设备等 struct net_device *input_dev; struct net_device *real_dev; union { #指向各协议层 header 结构 struct tcphdr *th; struct udphdr *uh; struct icmphdr *icmph; struct igmphdr *igmph; struct iphdr *ipiph; struct ipv6hdr *ipv6h; unsigned char *raw; } h; union { struct iphdr *iph; struct ipv6hdr *ipv6h; struct arphdr *arph; unsigned char *raw; } nh; union { unsigned char *raw; } mac; struct dst_entry *dst; #指向该 packet 的路由⽬的结构,告诉我们它会被如何路由到⽬的地 char cb[40]; # SKB control block,⽤于各协议层保存私有信息,⽐如 TCP 的顺序号和帧的重发状态 unsigned int len, #packet 的长度 data_len, mac_len, # MAC header 长度 csum; # packet 的 checksum,⽤于计算保存在 protocol header 中的校验和。发送时,当 checksum offloading 时,不设置;接收时,可以由device计算 unsigned char local_df, #⽤于 IPV4 在已经做了分⽚的情况下的再分⽚,⽐如 IPSEC 情况下。 cloned:1, #在 skb 被 cloned 时设置,此时,skb 各成员是⾃⼰的,但是数据是shared的 nohdr:1, #⽤于⽀持 TSO pkt_type, #packet 类型 ip_summed; # ⽹卡能⽀持的校验和计算的类型,NONE 表⽰不⽀持,HW 表⽰⽀持, __u32 priority; #⽤于 QoS unsigned short protocol, # 接收 packet 的协议 security;
发布者:admin,转转请注明出处:http://www.yc00.com/news/1690105625a306256.html
评论列表(0条)