注:文章非原创,来自极客时间 《趣谈网络协议》个人笔记
3.1 UDP协议
传输层有两个比较重要的协议,分别是TCP和UDP,其中TCP是面向连接的,UDP是面向无连接的,TCP互通会建立连接进行三次握手,而UDP并不会,建立连接是为了在客户端和服务端维护连接,维护双方的交互状态。
TCP提供了可靠交付,无差错、不丢失、不重复并且按照顺序到达。而UDO继承了IP包的特点,不保证不丢失,不保证按照顺序到达。
TCP是面向字节流的,发送的时候是一个流,没头没尾,UDP是基于数据报的,一个个发一个个收
TCP还拥有拥塞控制,根据网络环境调整窗口大小,UDP则没有
TCP是一个有状态服务,会记录发送没有接收没有,UDP则是无状态服务
UDP的包的格式会在IP头中显示,IP头上有个8位的协议会存放格式。其包头格式如下
UDP的三大特点第一是沟通简单,包结构非常简单,第二是容易发送和接收,第三是不会有拥塞控制。
UDP的使用场景基本为需要资源少,网络情况好,对包丢失不敏感的应用,不需要一对一沟通,建立连接,而是可以广播的应用。第三是需要处理快,时延低,可以容忍少数丢包的。
基于UDP发展的QUIC 快速UDP互联网连接是另外一种改进的通信协议,在应用层上,快速连接建立,减少重传时延,自适应拥塞控制
流媒体技术比如直播使用RTMP,是基于TCP的,还有网络游戏等,服务器能够维持的TCP连接是有限的,UDP是没有连接的。物联网技术、移动通信领域等。
3.2 TCP协议
TCP的包头格式如下TCP在不可靠的网络上保证可靠传输主要是不断的重传各种算法等。IP层是不会管丢不丢包的。
其中TCP的状态位有如下几个状态
SYN :发起一个连接
ACK:是回复
RST:是重新连接
FIN:是结束连接
TCP总结可以有如下几个特点
顺序问题,稳重不乱,
丢包问题,承诺靠谱,
连接维护,有始有终,
流量控制,把握分寸
拥塞控制,知道进退
TCP的三次握手主要为,请求--》应答--》应答的应答。三次握手除了是建立连接之外还是沟通双方TCP包的序号的问题。其中每个连接都有不同的序号,跟随时间变化,没4微秒加一,是一个32位的计数器。双方建立的时序图如下结构四次挥手过程
TCP状态机
TCP是如何保证可靠传出的呢?客户端发送的每一个包服务器都应该有个回复,如果服务器超过一定时间没有回复,客户端则重新发送包。TCP为了保证包的顺序性,每个包都有一个ID,在建立连接的时候商定ID是什么,然后按照ID一个个发,服务器也会一个个应答收到的包,这种模式叫做累计确认或者累计应答
TCP会将排队的包分为以下四个部分
发送了并且已经确认的、发送了并且尚未确认的、没有发送但是等待发送、没有发送暂时不会发送,在TCP里,接收端会给发送端上报一个窗口的大小,叫做Advertised window 这个窗口的大小等于上面第二部分加上第三部分对于接收端来说其窗口如下
其中MaxRcvBuffer代表最大缓存的量,LastByteRead之后是已经接收了但是还没被应用层读取的,NextByteExpected是第一部分和第二部分分界线。
其中窗口的大小等于 MaxRcvBuffer 减去接收已确认的。
当中间的某个数据包丢了,会进行超时重试,超时时间应该大于往返时间RTT。可以通过TCP通过采样RTT时间然后加权平均算出一个值,同时值自适应变化,叫做自适应重传算法。
注意TCP的再次重传的时候,超时时间会加倍。
流量控制方面,在对包的确认中,同时会携带一个窗口的大小,通过控制窗口rwnd移动和大小来控制数据的发送速率。避免把接收方的缓存塞满。
拥塞控制方面也是通过窗口的大小控制的,通过窗口cwnd,避免把网络塞满,避免包丢失和超时重传,一条TCP连接开始,cwnd设置为一个报文段,一次发送一个,每次确认加一。每次翻倍,指数增长
3.3 实际中的应用
使用基于TCP和UDP的Socket编程,Socket进行的是端到端的通信,在网络层Socket需要指定是IPv4还是IPv6分别设置AF_INET和AF_INET6还要指定是TCP还是UDP。
基于TCP的Socket编程,使用bind函数赋予IP和端口号,然后使用listen函数进行监听,系统内核中为每个Socket维护两个队列,分别是已经建立了连接的队列和还未建立的,使用connect函数发起连接,指定IP和端口号,发起握手内核会分配一个临时的端口,握手成功,服务端的accept返回另一个Socket,也就是监听的Socket和传输数据的Socket是两个,其基本流程如下
TCP就是Socket的一个文件流,Socket在Linux中就是文件流形式存在的,有发送队列和接收队列
基于UDP协议的Socket是没有连接的,所以不需要调用listen和connect,但是需要bind,如下是函数调用[图片上传失败...(image-fec441-1605617137871)]
开发服务端需要注意最大连接数,最大TCP连接数 = 客户端IP数 * 客户端端口数,针对IPv4 为2的32此房,端口为2的16次方,也就是最大连接数是2的48次方。
提高服务器连接能力,可以使用多进程方式或者多线程方式,使用线程池,利用服务器CPU多核能力,或者一个线程维护多个Socket使用Io多路复用