一、传输层协议:
- 负责应用程序之间的数据传输;UDP/TCP。
- 端口号的划分:(知名端口号)
ssh服务器, 使用22端口
ftp服务器, 使用21端口
telnet服务器, 使用23端口
http服务器, 使用80端口
https服务器, 使用443端口 - 查看端口号:cat /etc/services
- 端口范围划分:
(1)0~1023:知名端口号,是留着备用的,一般都是用于协议,例如HTTP、FTP、SSH ;
(2)1024~65535:是操作系统动态分配的端口号,客户端程序的端口号,就是由操作糸统从这个范围来分配的,在TCP与UDP的套接字通信中,客户端的端口号就是在此范围中。
二、UDP协议:
(一)udp协议端格式:
- udp首部的格式:
源端口–16位;(两字节)/目的端口–16位;(两字节):表示从那个程序发送到那个程序;
长度–16位;(两字节):包含udp报文头部在内的整体报文长度;
校验和–16位;(两字节):二进制反码求和算法。用于校验接收数据与发送数据是否保持一致;若为0,则数据一致;否则,表示数据不一致。
(二)udp的特点:
- 无连接:知道对端的IP和端口号就直接进行传输, 不需要建立连接
- 不可靠传输:通信过程中,并不保证数据安全可靠以及有序的床送到对端。
- 面向数据报传输:有最大传输长度限制的一种传输方式。
(1)实现:因为udp报文头部有一个数据报长度字段,最大数字为65535,限制了一个完整的udp报文的长度不得超过64k。
(2)对上层程序编写的影响:
- ①若sendto发送的数据长度大于64k-8,则会报错。udp报文头部8个字节;若数据过长,需要程序员手动对数据分割成一个个小的数据段(不大于64k-8)进行传输;
- ②因为udp不保证数据的有序到达,这时候在上层程序员对数据进行分包之后,就要在应用程对这些数据进行包序管理,确定先后顺序。
- ③udp报文头部定义了数据报的长度,因此数据包不能向上层交付半条或者多条数据,必须进行一整条交付,因此上层的就收baffer就要足够大。
(三)基于udp的应用层协议:
- NFS: 网络文件系统
- TFTP: 简单文件传输协议
- DHCP: 动态主机配置协议
- BOOTP: 启动协议(用于无盘设备启动)
- DNS: 域名解析协议
三、TCP协议:
(一)tcp协议端格式:
- 源端口–16位;/目的端口–16位:负责应用程序之间的传输;
- 序号–32位;确认序号–32位;实现确认应答机制;进行包序管理;
- 首部长度–4位:表示tcp首部的长度,tcp头部信息是不确定的,主要取决于选项数据的长度,以4字节为单位,tcp头部最少为20字节,最多60字节(选项数据0-40字节);
- 保留字–6位:保留为主要是留着以后对tcp内容进行扩展;
- 标志位–6位:URG/ACK/STN/FIN/RST/PSH;
- 窗口大小–16位:用于实现滑动窗口机制,进行流量控制;
- 校验和–16位:二级制反码求和,校验发送数据和接收数据是否一致性;
- 紧急指针–16位:标识紧急数据;
- 选项数据–32位:通常用于协商一些信息;
(二)tcp协议特点:
1.面向连接:
- 保证链接建立成功之后再发送数据;
2.可靠传输:
-
保证数据能够安全可靠到达对端(只要不是网络断开);
-
可靠传输的实现:确认应答机制/面向连接/超时重传机制/序号/确认序号/校验和;
-
避免丢包:滑动窗口机制/拥塞机制;
-
提高性能:快速重传机制/延迟应答机制/捎带应答机制;
(1)确认应答机制:
- 对于每条数据,都需要对方进行确认回复。
(2)超时重传机制:
- 对于传输的每条数据,指定时间内未收到确认应答,则认为数据丢失,将重新发送这条数据。
①确认序号:就是告诉发送方,这个确认序号以前的数据全部收到;协议字段的序号/确认信号:进行包序管理,实现确认应答机制。
②如果第一条数据缺失,就算收到后续的数据也不会进行回复,当回复发送方的时候,表明以前所有的数据都已经接收到;这个方式可以避免因为ACK确认回复丢失而导致重传。
③校验和:校验数据是否一致,不一致则要求重传;那一条数据不一致,则回复这条数据的起始序号;例如:1-1024的数据不一致,则返回序号1,要求对方重传1起始的数据。
(3)滑动窗口机制:
-
通过协议字段的窗口实现,通过窗口大小告诉对方最多发送多少数据,避免因为数据过多,接收缓冲区满溢导致的丢包问题。
①在三次握手时,通信双方会协商一个mss:MSS–最大数据段大小(应用层原始数据大小);tcp发送数据时,会从发送缓冲区中取出不大于MSS大小的进行数据封装tcp头部信息。
②窗口大小指的是无需等待确认应答而可以继续发送数据的最大值. 例如:窗口大小就是4000个字节(四个段).
③发送前四个段的时候, 不需要等待任何ACK, 直接发送;
收到第一个ACK后, 滑动窗口向后移动, 继续发送第五个段的数据; 依次类推;
④操作系统内核为了维护这个滑动窗口, 需要开辟发送缓冲区来记录当前还有哪些数据没有应答; 只有确认应答过的数据, 才能从缓冲区删掉;窗口越大, 则网络的吞吐率就越高; -
发送窗口:前沿减去后沿就是接收方告知窗口的大小;
①后沿:发送数据的起始序号;–后沿移动表示发送成功
②前沿:能够发送的数据的结束序号;–前沿移动取决接收方告知的窗口大小。 -
接收窗口:前沿减去后沿不大于接收缓冲区中剩余空间大小;
①后沿:接收数据的起始序号;–后沿移动是否收到起始序号的数据
②前沿:接收数据的结束序号;–前沿移动取决于缓冲区中剩余空间大小 -
流量控制:
①接收端将自己可以接收的缓冲区大小放入 TCP 首部中的 “窗口大小” 字段, 通过ACK端通知发送端;
②窗口大小字段越大, 说明网络的吞吐量越高;
③接收端一旦发现自己的缓冲区快满了, 就会将窗口大小设置成一个更小的值通知给发送端;
④发送端接受到这个窗口之后, 就会减慢自己的发送速度;
⑤如果接收端缓冲区满了, 就会将窗口置为0; 这时发送方不再发送数据, 但是需要定期发送一个窗口探测数据段, 使接收端把窗口大小告诉发送端.
(4)快速重传机制:
- 提高数据重传的效率:
发送方连续发送多条数据时,若接收方第一次接受的是第二次发送的数据,则有理由相信第一条数据可能丢失,因此向发送端连续发送三条重传请求,发送方接收到三次重传请求则会对数据进行重传。 - 三次:数据可能延迟,而并非丢失,三条重传里面有个缓冲时间,当在这三条重传时间段内收到了第一条数据,则就不用要求发送端重传数据了。
- 重传的三种协议:停等协议/选择重传协议/回退n步协议;
①停等协议:收到一条数据后才会重传第二条数据;
②选择重传协议:那条数据丢失,重传那条数据;
③回退n步协议:从丢失的数据开始,往后的数据都需要重传。
(5)拥塞机制:
- 滑动窗口实现一次连续发送多条数据,一开始在网络状态不明的情况下,有可能会因为网络差而导致数据发的越多,丢失的越多,因此,在发送数据的时候,先进行网络探测,查看网络是否能支持数据的连续快速传输,然后再进行数据传输。
- 慢启动,快增长:启动慢是因为要先进行网络探测,当探测完成,则会快速进行增长。
(6)延迟应答机制:
- 因为接收方若接受到数据就立即回复,则窗口大小会变小,吞吐率降低。
- 因而会采用延迟应答机制,延迟一段时间再进行确认回复,因为在延迟的这段时间内可能缓冲区的数据会被取走,从而窗口大小变大,吞吐率提高。
(7)捎带应答机制:
- 因为每一条数据发送出去都需要一个回复序号,则需要创建tcp数据包发送给对端,假如:客户端发送“hello ,nihao”,服务器需要回复“nihao”,那麽这个时候ACK就可以搭个顺风车,将确认回复和发送的数据同时发送给客户端,节省一个空报文的传输。
3. 面向字节流:
- 面向字节流:提供的是可靠的,有序的,基于连接的字节流传输;
- 字节流传输∶数据可以在缓冲区中进行堆积,取出比较灵活,以字节为单位进行存放/取出—传输比较灵活;
- 发送缓冲区中有很多数据,tcp就会根据mss取出合适大小的数据进行传输;接收缓冲区中有很多数据,tcp也可以灵活的以用户需要的大小向上交付。
(三)tcp中粘包问题:
1.粘包的形成:
- tcp传输层对数据边界不敏感,不管上层数据是什么样的,都根据mss取出合适大小进行发送/不管接收缓冲区是什莫,都直接在缓冲区中取出用户需要的大小的数据进行交付;从而导致粘包问题。
2.粘包的解决方案:(明确两个包之间的分界)
①对于定长的包, 保证每次都按固定大小读取即可; 例如上面的Request结构, 是固定大小的, 那么就从缓冲区从头开始按sizeof(Request)依次读取即可;
②对于变长的包, 可以在包头的位置, 约定一个包总长度的字段, 从而就知道了包的结束位置;
③对于变长的包, 还可以在包和包之间使用明确的分隔符(应用层协议, 是程序员自己来定的, 只要保证分隔符不和正文冲突即可)
3.对于UDP,是否存在粘包问题:
- 对于UDP, 如果还没有上层交付数据, UDP的报文长度仍然在. 同时, UDP是一个一个把数据交付给应用层. 就有很明确的数据边界.
- 站在应用层的角度, 使用UDP的时候, 要么收到完整的UDP报文, 要么不收. 不会出现"半个"的情况。所以不会出现粘包问题。
(四)基于tcp应用层协议:
- HTTP/HTTPS/SSH/Telnet/FTP/SMTP