TCP/UDP在传输层
IP地址标识主机,端口号标识运行在主机上的进程
在TCP/IP协议中,用"源ip","源端口号","目的IP","目的端口","协议号"这样个五元组来标识一个通信
udp/tcp 报文不会包含ip地址,只包含端口号
端口号划分
0-1023:知名端口号,HTTP, FTP. SSH等这些广为使用的应用层协议,他们的端口号都是固定的。
ssh服务,使用22端口
ftp服务使用21端口
telent服务 23端口
1024-65535:操作系统动态分配的端口号,客户端程序的端口号,就是由操作系统从这个范国分配的。一个进程是否可以绑定多个端口号?
可以,web服务器的进程绑定80(http)和 443(https)
一个端口可以绑定多个进程吗?
不行
netstat:查看网络状态
常用选项:
n 拒绝显示别名,能显示数字的全部转化成数字
l 仅列出有在 Listen(监听)的服务状态
p 显示建立相关链接的程序名
t 只显示tcp相关选项
u 只显示udp选项
a 显示所有选项,默认不显示LISTEN相关
UDP
报头为定长8个字节
抓包软件
udp是面向数据报的:发送一次,对应接收一次。
UDP的缓冲区
UDP没有发送缓冲区,不会把报文组合再发送,是直接交给内核。
正是因为没有发送缓冲区,所以udp是面向数据报。
UDP有接收缓冲区,但这个缓冲区不能保证接收和发送一致,如果满了,到达的udp报文会被丢弃。
UDP是全双工:UDP的socket既能够读,又能够写
UDP的报文长度是16位长度,意味着最大是64kb
UDP报头和载荷如何分离?
报头为定长,取报文的前8个字节
基于UDP的应用层协议
NFS:网络文件系统
TFTP:简单文件传输协议
DHCP:动态主机配置协议
BOOTP:启动协议(无盘设备启动)
DNS:域名解析协议
TCP
TCP报文
报头字段解析
4位首部长度表示报头大小,单位是4个字节 范围是[0000,1111]=[0,15], 报头长度是[0,60]
16位窗口大小: 自己的接收缓冲区剩余大小(即接收能力),为对方流量控制提供参考。
客户端和服务器通信时发送的完整的报头
TCP有两个缓冲区:发送缓冲区和接收缓冲区
read,recv,send的函数调用,本质并不是数据发送到网络当中,而是发送到内核缓冲区
本质上是拷贝数据到内核缓冲区,数据什么时候发送,发送多少,出错了怎么办,由TCP协议自主决定
TCP也是全双工,既能过一个文件描述符fd读,也能写。原因是因为有两个文件缓冲区
UDP 没有发送缓冲区,直接发送
TCP有发送缓冲区,可以将多个报文整合到一起再发送,因此TCP不是面向报文流的,而是面向字节流的。
流量控制:基于对方缓冲区,控制客户端和服务端通信数量,避免缓冲区太满导致丢包。
确认应答机制:保证可靠性的一个基本特点,当客户端/服务器发信息,另一方返回一个应答
确认应答机制
保证可靠性的一个基本特点,当客户端/服务器发信息,另一方返回一个应答
应答机制只能确认以往的消息,最新的消息无法确定,不再对应答发送二次应答。
客户端和服务器各发送请求,保证两个方向上的可靠性。
稍带应答:服务器可以把应答和tcp数据合在一起发
32位序号和32位确认序号
序号
类似于数组下标保证报文按序到达,或者乱序到达后,能排好序。
从用户层拷贝下到tcp的发送缓冲区时,连续的字符串被拆成多个字节,天然每个字节都有自己的序号,类似于数组下标
序号就是报文数据的最后一个下标,根据序号来重新组合发送的数据
确认序号
对之前收到的报文的应答,结果为收到的报文的序号+1,表示确认序号之前的数据已经收到。告知用户端下次发送请从确认序号+1字符开始发送
如确认应答为1001,说明 0~1000的应答都收到了。如果中间报文丢失了,确认序号为已收到的报文的序列号+1
发送 1000,2000,3000, 其中2000丢失,那么3000报文的应答是1001
好处:可以允许应答有少量丢失,即使前面应答有少量丢失,也可以根据后面的应答来确定前面是否收到。
确认序号和序号同时存在的原因
既可能是应答也是同时发送数据。
tcp是全双工,服务器和客户端同时发送消息和应答。
一个服务器可能会给多个服务端服务。
6个标志位
tcp通信建立连接,断开连接,正常数据通信都需要发送不同类型的tcp报文,tcp通过标志位来区分不同的tcp报文类型
ACK:确认序号位是否有效,默认为1,不携带数据就是应答,有数据就是稍带应答。
SYN:请求建立连接,携带syn的标志位报文叫同步报文段,在三次握手时发送。
FIN:通知接收方,本端要关闭了。
PSH:PSH设为1,提示接收方清空接收缓存区。
RST:对方要求重新建立连接,RST标识的报文称为复位报文段。
URG: 0,紧急指针无效,1,紧急指针有效。
RST应用场景
客户端在第二次发送ACK连接时,不收到应答就认为连接成功,而服务器端认为接收到ack才认为连接成功。
(服务器没有收到最后第三次ack时)服务器端要发送rst标志位,提醒客户端重新建立三次连接
(最后一个ack没有应答,客户端不知道服务端是否收到),client只要把第三次的ack发送过去,就认为建立好
然而当ack发送失败,服务端要发送rst标志位的报文,提醒客户端重新建立连接
URG应用场景
数据插队,优先读取某些重要数据,urg为0,紧急指针无效,urg为1,紧急指针有效。
紧急指针为数据中紧急数据的偏移量,系统会优先处理紧急数据。
紧急数据一般为一字节,一般一个报文只有一个紧急数据。
场景:当服务器出现问题,发送紧急数据,询问服务器情况,服务器返回紧急数据给客户端。
TCP可靠性策略
确认应答机制
在TCP报文的下个小节
超时重传机制
主机对于发出的报文是否丢失,只能通过应答判断,主机在一段时间内没有收到应答时,重新发送。
主机收到重复报文时,如何处理?
接收端可能收到重复报文,通过序号去重。
超时时间如何确定?
超时时间和网络有关,是动态的而且和网络状态强相关。
在linux以500ms为单位控制,且指数增加。
超时时间为500ms*2^n(n=0,1,2,3)
如第一次 2*500ms 第二次 4*500ms。
TCP的连接管理机制
连接流程
connect负责发起三次握手,客户端发送应答时ESTABULISH。(connect返回)
accept不发起握手,服务器收到ACK后,三次握手完成,accept返回。
客户端和服务器发送连接
closefd(fd) 关闭连接,发送FIN标志的TCP报文,服务器端返回ACK,客户端不再发送数据。(但可以发送管理报文,ACK)
(相当于写端关闭,读端不变)
此时服务器端可以再发送数据给客户端,当服务器端不再发送数据了,发送FIN报文,客户端返回ACK,此时表明双方都不再通信,结束连接。
TCP通信是基于连接的,有三次握手和四次挥手
为什么有三次握手?
实际上是四次,服务端的ack和syn合成一次。
保证客户端和服务端至少有一次收和发,验证全双工通路是否通畅。
一次握手客户端可以快速多次发送syn请求,可能导致syn洪水。
两次握手:优先让服务器优先建立连接,如果连接失败,会导致失败的连接在服务端
三次握手:奇数次握手,确保服务器建立连接时,客户端是没问题的。保证连接失败的情况在客户端。
为什么四次挥手?
第二次的ACK和FIN不可以合并,因为可能服务器端还要发送数据给客户端。
(写端关闭了,读端打开)
确保双方都知道对方不想发送数据
连接建立是否成功和accept没有关系,accpet函数没有调用,连接的建立状态依然是ESTABUSHED
Listen函数
listen参数的第二个是blacklog,blacklog+1表示可以建立的连接数目
对于建立好的连接,底层用一个队列维护,blacklog+1表示队列长度
超过最大连接长度的连接,服务端连接的状态是SYN_RCVD,原因是服务器端接收到ACK,但不做响应,连接的状态无法转变成ESTABUSHED
server 端不会长时间维护syn_recv状态的连接,这种连接叫半连接
半连接syn洪水:大量发送半连接,消耗半连接队列(像全连接一样,半连接也有队列)
blackblog为什么不能太长?为什么不能没有?
将资源更多地用于处理其他事务,而不是维护连接。没有队列,则不能将资源充分利用。(有点类似于池)
TIME_WAIT状态
主动断开连接的一方在最后四次挥手后进入TIME_WAIT状态,等待若干时长,自动释放
Server主动断开连接,服务器方进入TIME_WAIT状态,连接没有被彻底断开。
ip和port正在被使用,ip和sort组合只能绑定一个进程,TIME_WAIT时间内服务器无法立即重启,出现bind失败问题。
Setsocket套接字,允许地址服用,使得TIME_WAIT内时间内服务器可以重启
客户端不受影响,因为客户端用的是随机端口。
TIME_WAIT的时间为什么是2MSL?
MSL是TCP报文的最大生存时间(不是传送时长),因此TIME_WAIT持续存在2MSL的话就能保证在两个传输方向上的尚末被接收或迟到的报文段都已经消失(否则服务器立刻重启,可能会收到来自上一个进程的迟到的数据,但是这种数据很可能是错误的)
同时也是在理论上保证最后一个报文可到达(假设后最后一个ACK丢失,那么服务器会再第发一个FIN。这时虽然客户端的进程不在了,但是TCP连接还在,仍然可以重发LAST_ACK。
TCP流量控制
根据接收方的缓冲区的大小来决定发送方的速度
报文16位窗口大小字段携带发送方接收缓冲区剩余空间大小,给接收方发送数据作参考。
第一次发送,怎么保证发送数据量是合理的?
三次握手在握手时,交换了对方的接收数据的能力,第三次握手ack可以携带数据。说明信息交换是在第二次。
当缓冲区满的时候,主机A会发送窗口探测,检测B的缓冲区剩余空间大小,同时主机B的缓冲区更新后也会发送窗口更新通知。窗口探测和窗口更新通知都是报头。
TCP首部40个字节选项包含一个窗口扩大因子M,实际窗口大小是窗口字段左移M位。
流量控制属于可靠性(减少数据丢失),也属于效率