传输层协议有TCP和UDP,TCP是一种面向连接的可靠地传输协议,UDP则无连接尽力而为的传输
TCP报文结构:
固定首部长度为20字节,可变部分0~40字节,各字段解释:
source port number:源端口,16bits,范围0~65525。
target port number:目的端口,16bits,范围同上。
sequence number:数据序号,32bits,TCP 连接中传送的数据流中的每一个字节都编上一个序号。序号字段的值则指的是本报文段所发送的数据的第一个字节的序号。
acknoledgement number:确认号,32bits,期望收到对方的下一个报文段的数据的第一个字节的序号。
header length:数据偏移,4bits,单位为4字节,它指出报文数据距TCP 报头的起始处有多远(TCP报文头长度)。
reserved:保留字段(图中,包含CWR,ECE),6bits,保留今后使用,目前置0处理。
URG:紧急比特,1bit,当 URG=1 时,表明紧急指针字段有效。它告诉系统此报文段中有紧急数据,应尽快传送(相当于高优先级的数据)。
ACK:确认比特,1bit,只有当 ACK=1 时确认号字段才有效。当 ACK=0 时,确认号无效。
PSH:推送比特,1bit,接收方 TCP 收到推送比特置1的报文段,就尽快地交付给接收应用进程,而不再等到整个缓存都填满了后再向上交付。
RST:复位比特,1bit,当 RST=1 时,表明 TCP 连接中出现严重差错(如由于主机崩溃或其他原因),必须释放连接,然后再重新建立运输连接。
SYN:同步比特,1bit,同步比特 SYN 置为 1,就表示这是一个连接请求或连接接受报文。
FIN:终止比特,1bit,用来释放一个连接。当FIN=1 时,表明此报文段的发送端的数据已发送完毕,并要求释放运输连接。
window size:窗口大小,16bits,窗口字段用来控制对方发送的数据量,单位为字节。TCP 连接的一端根据设置的缓存空间大小确定自己的接收窗口大小,然后通知对方以确定对方的发送窗口的上限。
checksum:检验和,16bits,检验和字段检验的范围包括首部和数据这两部分。在计算检验和时,要在 TCP 报文段的前面加上 12 字节的伪首部。
urgent pointer:紧急指针字段,16bits,紧急指针指出在本报文段中的紧急数据的最后一个字节的序号。
options:选项字段,长度可变。TCP 首部可以有多达40字节的可选信息,用于把附加信息传递给终点,或用来对齐其它选项。
TCP连接建立过程中要解决以下三个问题:
要使每一方能够确知对方的存在。
要允许双方协商一些参数(如最大报文段长度,最大窗口大小,服务质量等)。
能够对运输实体资源(如缓存大小,连接表中的项目等)进行分配。
在TCP传输连接的建立和释放中的通信双方主机的这些状态称之为“有限状态机”(Finite State Machine,FSM)
对于每一种应用层协议想要进行通信,就必须通过IPC机制进行实现,Socket(套接字)是IPC的一种实现,程序调用socket API向内核注册端口,实现位于不同主机(甚至同一主机)上不同进程之间进行通信;数据交换。套接字有三种:
SOCK_STREAM:tcp套接字
SOCK_DGRAM:udp套接字
SOCK_RAW: 裸套接字(不基于tcp和udp直接基于ip地址实现进程间通信)
其实套接字就是ip地址和端口的组合,ip地址我相信不需缀余,我们分析一下传输层的端口:
tcp:传输控制协议,面向连接的协议;通信前需要建立虚拟链路;结束后拆除链路;
0-65535
udp:User Datagram Protocol,无连接的协议;
0-65535
对于这些端口:
0-1023:众所周知,永久的分配给固定的应用使用,特权端口,22/tcp(ssh), 80/tcp(http), 443/tcp(https)
1024-41951:亦为注册端口,但要求并不是特别严格,分配给程序注册为某应用使用,11211/tcp, 11211/udp (memcached), 3306/tcp(mysql)
41952+:客户端程序随机使用的端口;动态端口,或私有端口;在linux主机上我们可以自定义其范围,其范围的定义:/proc/sys/net/ipv4/ip_local_port_range
下面我们来分析一下传输层的TCP和UDP协议:
TCP协议的特性:
1.建立连接:三次握手
2.将数据打包成段:校验和(CRC-32),一般路由设备的MTU(最大传输单元为1500byte,为了防止数据包过大,我们需要把数据拆分成段逐个发送)
3.确认、重传以及超时:确保传输中数据的完整性
“超时重传”是TCP协议保证数据可靠性的一个重要机制
其原理是在发送某一个数据段以后就开启一个超时重传计时器(Retransmission Timer,RTT),如果在这个定时器时间内如果没有收到来自对方的某个数据段的确认,发送端则启动重传机制,重新发送对应的数据段,直到发送成功为止
快速重传/快速恢复
“快速重传”方案的基本思想就是:当接收端收到一个不是按序到达的数据段,TCP实体迅速发送一个重复ACK数据段,而不用等到有数据需要发送时顺带发出确认;在重复收到三个重复ACK数据段后即认为对应“确认号”字段的数据段已经丢失,TCP不等重传定时器超时就重传看来已经丢失的数据段。
4.排序:逻辑序号:数据包被拆分逐个发送到目的方后需要恢复组建回原状,为了防止数据包组建紊乱,需要用到排序
5.流量控制:滑动窗口算法,防止快发慢收,或者慢发快收,发送端和目的端发送速度不同步会造成拥堵
6.拥塞控制:慢启动和拥塞避免算法,数据包发送前会发送一个探针包去探测链路状态,如果没问题才继续发送,如果发生拥堵则等待
慢启动是为了避免出现网络拥塞而采取的一种TCP拥塞初期预防方案。基本思想就是在TCP连接正式数据传输时,每次可发送的数据大小是逐渐增大的,也就是先发送一些小字节数的试探性数据,在收到这些数据段的确认后,再慢慢增大发送的数据量,直到到达了某个原先设定的极限值,也就是“慢启动阈值”。
当拥塞窗口大小再次达到大于或等于阀值时就启动“拥塞避免”拥塞解决方案。它的基本思想是在拥塞窗口值第二次到达到了阀值时,让“拥塞窗口”大小每经过一个RTT时间仅值加1(即新的拥塞窗口只增加一个MSS大小,而不是原来的翻倍),使其以线性方式慢慢地增大,而不是继续像“慢启动”方案中那样以指数方式快速增大。
Socket Domain(根据其所使用的地址):
AF_INET:Address Family,IPv4
AF_INET6:IPv6
AF_UNIX:同一主机上不同进程之间通信时使用;这种方式不需要经过通信子网(TCP/IP的下三层),通过内核直接走应用子网(应用层,传输层)进行通信。而上面两种因为是跨主机通信,所以经过TCP/IP的网络层,数据链路层,物理层是必须的
每类套接字都至少提供了两种socket:流,数据报
流:tcp发送是基于流的,可靠地传递、面向连接、无边界;
数据报:udp发送是基于数据报的,不可靠地传递、有边界(发送数据包时数据报都会告知接收方报文 从哪里开始,哪里结束)、无连接;
编程中套接字相关的系统调用:
socket(): 创建一个套接字;
bind():绑定
listen():监听
accept():接收请求
connect():请求连接建立
write():发送
read():接收
send(), recv(), sendto(), recvfrom()
转载于:https://blog.51cto.com/leeyan/1696287