一、OSI分层模型
应用层:http、ftp、nfs、ssh、telnet
传输层:TCP、UDP
网络层:IP、ICMP、IGMP
链路层:以太网帧协议、ARP
ARP协议:根据 指定IP 地址获取mac地址. (mac地址是计算机的唯一标识)
两步:1.请求
源主机发送不完整的ARP数据报请求(有源IP、mac地址及指定对端IP,无指定IP对应主机的mac地址)。
2.应答
通过源主机发送请求后,对端主机会发送相应的应答将完整的ARP数据报应答给源主机。
以太网帧协议: 根据mac地址,完成数据包传输。
二、网络通信
-
基础
数据没有经过如下图所示封装,是不能再网络中传输的。 数据封装时是由: 应用层 -> 传输层 ->网络层 -> 链路层 网络传输时: 链路层有两步: 1.ARP请求和应答,获取到完整ARP数据报信息。 2.合成以太网帧。
-
IP协议(网络层)
版本:IPv4、IPv6 TTL:time to live 设置数据包在路由结点(路由器)中的跳转上线。每经过一个路由结点,该值-1,减为0的路由结点有义务将该数据包丢弃。 源IP、目的IP : 32 位。4字节。 192.168.1.1 ——点分十进制(string类型)。 实际应计算机中为二进制。
-
TCP、UDP(传输层)
IP地址:可以在网络环境中,唯一标识一台主机。 端口号:可以在网络的一台主机上,唯一标识一个进程。 IP地址+端口号 :可以在网络中,唯一标识一个进程。 UDP: 16位:源端口号 2^16 = 65536 16位:目的端口号 TCP: 16位:源端口号 2^16 = 65536 16位:目的端口号 32位序号 32位确认序号:用于确认接收端是否成功接收指定数据 6个标志位 16位窗口大小。 2^16 = 65536
如上图所示: 32位序号 :对应 SYN 的 数据包包号 32位确认号 :对应ACK的 数据包包号 一般为收到的 SYN号+1 16位窗口大小
三、B/S、C/S模型
C/S | B/S | |
---|---|---|
全称 | client server | browser server |
优点 | 缓存大量数据,协议选择灵活(可以自定义协议,例:QQ) | 安全性、跨平台、开发量小 |
缺点 | 安全性、跨平台、开发量大 | 不能缓存大量数据、必须遵守http协议 |
四、TCP——数据报格式详解
如上图所示:
32位序号 :对应 SYN 的 数据包包号
32位确认号 :对应ACK的 数据包包号 一般为收到的 SYN号+1
16位窗口大小: 滑动窗口大小(可接收数据缓存大小的概念)。
五、TCP——三次握手及四次挥手 (标志位 SYN、ACK)
TCP三次握手发生在内核中,代码上的体现是,函数accept()和connect()成功返回。
三次握手:
主动连接请求端,发送 SYN 标志位,请求建立连接。携带 序号、数据字节数(0)、滑动窗口大小。
被动接受连接请求端,发送 ACK 标志位,携带 SYN 请求标志位、序号、确认序号、数据字节数(0)、滑动窗口大小。
主动发起连接请求端,发送 ACK 标志位,应答服务器连接请求。携带 确认序号。
四次挥手:
主动关闭连接请求端,发送 FIN 标志位。
被动关闭连接请求端,应答 ACK 标志位。 ————半关闭完成
被动关闭连接请求端,发送 FIN 标志位。
主动关闭连接请求端,应答 ACK 标志位。 ————全关闭完成
对下图解释:
【TCP连接三次握手】:
第 1 次握手:
发起连接的一般为 client 端,发起时携带 标志位SYN 及 数据包包号(随机,图示为1000)以及 数据包的大小(图示为0,表示纯建立连接),
mss 1460代表数据包上线为1460(和以太网帧有关,详见上面TCP/IP数据包图片)。
第 2 次握手:
server端响应第一次握手的应答,携带 标志位ACK 及 响应数据包包号(客户端包号+1,图示为1001,代表1001之前的包都收到了)。(客户端包号+1的原因是ACK标志位本身 1 字节)
mss 1024,代表响应数据包的大小为1024.
server端与此同时发送请求连接的请求携带 标志位SYN 和 及 数据包包号(随机,图示为8000)以及 数据包的大小(图示为0,表示纯建立连接)。
第 3 次握手:
client端响应第 2 次握手server端的连接请求,并携带 标志位ACK 及 响应数据包包号(客户端包号+1,图示为8001,代表8000之前的包都收到了)。
至此三次握手连接完毕。
数据传输:
第 1 次传输(client端发送数据):
client端发送包号1001 及20字节数据,并将三次握手的最后一次ACK 也携带过去(TCP是稳定连接的特性)。
第 2 次传输(server端确认并发送数据):
server端发送 确认标志位ACK 1021(接收到的SYN的1001+20字节大小数据=1021),以及自身的响应数据包 8001及10字节大小的数据
第 3 次传输(client端确认接收的数据):
client端响应server端的数据请求,发送 确认标志位ACK 8011(接收到的8001+10字节大小数据=8011).
【TCP断开四次挥手(结合socket编程好理解)】:
第 1 次挥手:
client端 发送FIN标志位及 数据包号1021及0字节数据,并发送上一次的ACK 8011(TCP稳定连接的特性)
第 2 次挥手:
server端发送 标志位ACK 1022,响应client端的FIN标志位 1021。
至此半关闭完成,client端 socket的写缓冲区关闭,仍可读。
第 3 次挥手:
server端因为接收到FIN后,等待合适的时机就主动发送 FIN标志位。及上一个 响应标志位ACK 1022(TCP稳定连接的特性)
第 4 次 挥手:
client端接收到server端的FIN后,就发送响应ACK 8012 。
至此TCP连接完全断开。
六、TCP——滑动窗口大小
——————————————————————————需要好好理解!!!
如下图所示:
滑动窗口
本质类似于一个数据接收缓冲区。该窗口存在于通讯两端。
【发送给连接对端,本端接收数据缓冲区实时大小】,保证数据不丢失。
sender:
发送时:
总是会将本地滑动窗口可用大小(可接收数据缓冲区大小)随TCP报文发送给对方,以便对方发送数据给己方时判断要发多少数据或者等待(等有足够大小时再发)。
例:如下图的1、 3~9 中的win 4096,因为sender始终在发送,故它的接收区大小始终为4096。
接收时:
接收到对方 滑动窗口win 的大小。
例:如下图 2、10~11。
由下图 2 知道receiver的窗口大小为6144,
4~9接收了5121的数据,
sender每次发送1024,而 5121+1024 = 6145 > 6144,故 sender会选择等待,直到receiver拥有足够的空间接收数据,10~11就是因为对端滑动窗口太小而出现的发送等待。
拥有空间后(10~11 receiver释放空间),CPU择机再次发送(例图中 12)。
receiver:
发送时:
总是会将本地滑动窗口可用大小(可接收数据缓冲区大小)随TCP报文发送给对方,以便对方发送数据给己方时判断要发多少数据或者等待(等有足够大小时再发)。
例:如下图2、10~11、14~17
接收时:
如下图 3~9。始终能够直到对端滑动窗口大小 win 4096.
七、TCP——通讯流程
八、TCP——状态转换(重点,一定要记清楚)
查看状态的命令:
netstat -apn | grep client
netstat -apn | grep server
netstat -apn | grep 10001
1.主动发起连接请求端:
CLOSE --发送SYN --> SYN_SEND --接收ACK、SYN --> 保持SYN_SEND --
发送 ACK--> ESTABLISHED(数据通信态)
2.主动关闭连接请求端:
ESTABLISHED(数据通讯态)--发送FIN --> FIN_WAIT1 --接收ACK-->FIN_WAIT2(半关闭)--
接收对端发送FIN--> 保持FIN_WAIT2(半关闭)--回发ACK--> TIME_WAIT(等待 2MSL 时长) ---->close
【只有主动关闭连接端才会经历TIME_WAIT状态】
因此,先关闭服务端,再关闭client端后,再次启动服务端会出现bind error的原因。
要想避免此种报错,可以使用 【套接字选项 setsocket()函数】。详见Unix网络编程 第 7 章。
3.被动接收连接请求端:
CLOSE ---->LISTEN ---接收SYN-> 保持LISTEN --发送ACK、SYN--> SYN_RCVD --
接收ACK--> ESTABLISHED(数据通信态)
4.被动关闭连接端:
ESTABLISHED(数据通讯态)--接收FIN--> 保持 ESTABLISHED --发送ACK--> CLOSE_WAIT(主动关闭端处于半关闭态) --接收ACK
--> CLOSE
TIMEWAIT 的 2MSL:
它的存在是为了保证对端收到 主动关闭一端的 ACK 能被对方接收。但仍需保证主动关闭一端能正常关闭。
在主动关闭一端的 2MSL 时间内会持续发送ACK,以尽可能使对端收到。
极端情况:
1.被动接收连接请求端,收不到最后一个ACK,内核会设置 RST 标志位,重启连接。
2.CLOSEING状态 出现与两端同时进行关闭操作。