TCP/IP

TCP/IP

管理员
2025年6月21日· 已更新
运维
网络

来源于B站:https://www.bilibili.com/video/BV1cF411p7PM

从用户空间、tcp、ip、链路层角度进手

IO模型与网络相关

1.tcp/ip在开发中的作用

网络有两个词一定要懂:OSI7层参考模型、TCP/IP协议

分层解耦:每个层干自己的事情

OSI7层模型

7 应用层

6 表示层

5 会话层

4 传输层

3 网络层

2 数据链路层

1 物理层

普通交换机只有两层:链路层、物理层

三层交换机/路由器有三层:网络层、链路层、物理层

TCP/IP

5 应用层 (把应用层、表示层、会话层统称为应用层了)

4 传输控制层 (tcp、udp)

3 网络层 (ip、arp)

2 链路层 (mac)

1 物理层

源端口号-->目标端口号

源IP地址-->目标IP地址

源MAC地址-->目标MAC地址

结论:

TCP/IP协议基于下一跳机制:IP是端点间,mac地址是节点间的

程序分两大类:application、内核

应用层协议:http、https、ssh、

协议:双方约定的,数据包传输的表示形式

不同软件需要不同的协议,就是各自能懂的语言

程序员操作应用层,传输控制层、网络层、链路层、物理层封装在内核中,公共使用的,程序可以直接调用。

程序在用户空间,内核在内核空间

2.什么是应用层的http协议(应用层)

想从百度的服务器把主页请求回来?

环回接口lo

一个完整的请求过程需要四部:连接、发送请求、响应、关闭

tcpdump -nn -i eth0 抓取eth0网卡的数据包

tcpdump -nn -i eth0 port 80 抓取端口号80的数据包

-n 以数字形式显示ip地址,不带-n就是显示主机名

-i 指定网卡

建立连接

exec 8<> /dev/tcp/www.baidu.com/80 # 8在这里只是充当一个变量


建立连接,发生三次握手,tcpdump抓取80端口可以查看对应报文

[root@localhost ~]# tcpdump -nn -i ens33 port 80
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ens33, link-type EN10MB (Ethernet), capture size 262144 bytes
13:19:50.405392 IP 192.168.10.20.33966 > 14.215.177.38.80: Flags [S], seq 309429392, win 29200, options [mss 1460,nop,nop,sackOK,nop,wscale 9], length 0
13:19:50.415758 IP 14.215.177.38.80 > 192.168.10.20.33966: Flags [S.], seq 3536284474, ack 309429393, win 8192, options [mss 1430,nop,nop,sackOK,nop,wscale 5], length 0
13:19:50.415795 IP 192.168.10.20.33966 > 14.215.177.38.80: Flags [.], ack 1, win 58, length 0

1.客户端33966向服务端80发送请求
2.服务端80回复同意请求
3.客户端向服务端80确认


[root@localhost ~]# netstat -natp
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 127.0.0.1:25            0.0.0.0:*               LISTEN      1077/master
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      987/sshd
tcp        0      0 192.168.10.20:22        192.168.10.1:64042      ESTABLISHED 1403/sshd: root@pts
tcp        0      0 192.168.10.20:22        192.168.10.1:64400      ESTABLISHED 1439/sshd: root@pts
tcp        0      0 192.168.10.20:33966     14.215.177.38:80        ESTABLISHED 1513/-bash
tcp6       0      0 ::1:25                  :::*                    LISTEN      1077/master
tcp6       0      0 :::22                   :::*                    LISTEN      987/sshd


查看网络连接,能发现刚刚本机33966与百度服务端80建立的请求,socket状态是establish

netstat -natp 会显示网络连接

-t tcp协议

协议 Recv-Q(接收队列) Send-Q(发送队列) 本地地址 远端地址 状态 PID/程序名称

每行被称作一个socket,一个socket是由一个四元组组成的,即ip:port

socket分两大类:监听的(LISTEN)、建立连接的(ESTABLISHED)

与www.baidu.com的连接已经建立了,怎么请求主页?

baidu.com是web服务器,那就要走web协议,就是http协议

http协议是有http方法的,

先本地打印:echo "GET / HTTP/1.0\n" 最后是换行符

echo -e "GET / HTTP/1.0\n" # -e是转换最后换行符的

[root@localhost ~]# echo "GET / HTTP/1.0\n"
GET / HTTP/1.0\n

[root@localhost ~]# echo -e "GET / HTTP/1.0\n"
GET / HTTP/1.0


获取baidu主页

echo -e "GET / HTTP/1.0\n" >& 8 # 输出重定向给前面定义的变量8

查看baidu主页内容

[root@localhost ~]# cat <& 8

HTTP/1.0 200 OK

Accept-Ranges: bytes

Cache-Control: no-cache

Content-Length: 9508

Content-Type: text/html

Date: Sat, 12 Feb 2022 08:51:20 GMT

P3p: CP=" OTI DSP COR IVA OUR IND COM "

P3p: CP=" OTI DSP COR IVA OUR IND COM "

Pragma: no-cache

Server: BWS/1.1

Set-Cookie: BAIDUID=48BC5A1AAD87DA6B1D60B0411F9F4349:FG=1; expires=Thu, 31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com

Set-Cookie: BIDUPSID=48BC5A1AAD87DA6B1D60B0411F9F4349; expires=Thu, 31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com

Set-Cookie: PSTM=1644655880; expires=Thu, 31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com

Set-Cookie: BAIDUID=48BC5A1AAD87DA6B552A0E144C5C4AD8:FG=1; max-age=31536000; expires=Sun, 12-Feb-23 08:51:20 GMT; domain=.baidu.com; path=/; version=1; comment=bd

Traceid: 164465588003728634989399221463304205787

Vary: Accept-Encoding

X-Frame-Options: sameorigin

X-Ua-Compatible: IE=Edge,chrome=1


tcpdump抓取的80端口也显示有新内容

[root@localhost ~]# tcpdump -nn -i ens33 port 80
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ens33, link-type EN10MB (Ethernet), capture size 262144 bytes


17:05:51.685967 IP 192.168.10.20.33972 > 14.215.177.38.80: Flags [P.], seq 2909056386:2909056401, ack 1912743580, win 58, length 15: HTTP: GET / HTTP/1.0
17:05:51.696545 IP 14.215.177.38.80 > 192.168.10.20.33972: Flags [.], ack 15, win 908, length 0
17:05:51.696574 IP 192.168.10.20.33972 > 14.215.177.38.80: Flags [P.], seq 15:16, ack 1, win 58, length 1: HTTP
17:05:51.705921 IP 14.215.177.38.80 > 192.168.10.20.33972: Flags [.], ack 16, win 908, length 0
17:05:51.707408 IP 14.215.177.38.80 > 192.168.10.20.33972: Flags [P.], seq 1:4073, ack 16, win 908, length 4072: HTTP: HTTP/1.0 200 OK
17:05:51.707421 IP 192.168.10.20.33972 > 14.215.177.38.80: Flags [.], ack 4073, win 73, length 0
17:05:51.707444 IP 14.215.177.38.80 > 192.168.10.20.33972: Flags [.], seq 4073:5493, ack 16, win 908, length 1420: HTTP
17:05:51.707451 IP 192.168.10.20.33972 > 14.215.177.38.80: Flags [.], ack 5493, win 79, length 0
17:05:51.709223 IP 14.215.177.38.80 > 192.168.10.20.33972: Flags [P.], seq 5493:10473, ack 16, win 908, length 4980: HTTP
17:05:51.709235 IP 192.168.10.20.33972 > 14.215.177.38.80: Flags [.], ack 10473, win 99, length 0
17:05:51.709256 IP 14.215.177.38.80 > 192.168.10.20.33972: Flags [F.], seq 10473, ack 16, win 908, length 0
17:05:51.716158 IP 14.215.177.38.80 > 192.168.10.20.33972: Flags [F.], seq 10473, ack 16, win 908, length 0
17:05:51.716169 IP 192.168.10.20.33972 > 14.215.177.38.80: Flags [.], ack 10474, win 99, options [nop,nop,sack 1 {10473:10474}], length 0

注意:F是FIN分手 (三次握手,四次分手)、P是推送,数据推送

tcpdump中可以看到,获取了主页后,baidu80就出现了F,就是断开连接,但这里只有两次FF,还有两次分手呢?

netstat -natp 查看连接也发现baidu80的socket状态是关闭等待的

[root@localhost ~]# netstat -natp
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 127.0.0.1:25            0.0.0.0:*               LISTEN      1077/master
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      987/sshd
tcp        0      0 192.168.10.20:22        192.168.10.1:64400      ESTABLISHED 1439/sshd: root@pts
tcp        0      0 192.168.10.20:49750     14.215.177.39:80        CLOSE_WAIT  1513/-bash

关闭exec进程

exec 8>& -

tcpdump可以发现,后两次FF也出现了

17:05:51.709223 IP 14.215.177.38.80 > 192.168.10.20.33972: Flags [P.], seq 5493:10473, ack 16, win 908, length 4980: HTTP
17:05:51.709235 IP 192.168.10.20.33972 > 14.215.177.38.80: Flags [.], ack 10473, win 99, length 0
17:05:51.709256 IP 14.215.177.38.80 > 192.168.10.20.33972: Flags [F.], seq 10473, ack 16, win 908, length 0
17:05:51.716158 IP 14.215.177.38.80 > 192.168.10.20.33972: Flags [F.], seq 10473, ack 16, win 908, length 0
17:05:51.716169 IP 192.168.10.20.33972 > 14.215.177.38.80: Flags [.], ack 10474, win 99, options [nop,nop,sack 1 {10473:10474}], length 0
17:07:59.936638 IP 192.168.10.20.33972 > 14.215.177.38.80: Flags [F.], seq 16, ack 10474, win 99, length 0
17:08:00.147353 IP 192.168.10.20.33972 > 14.215.177.38.80: Flags [F.], seq 16, ack 10474, win 99, length 0


查看连接状态,已经没有baidu80的socket了

[root@localhost ~]# netstat -natp
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 127.0.0.1:25            0.0.0.0:*               LISTEN      1077/master
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      987/sshd
tcp        0      0 192.168.10.20:22        192.168.10.1:64400      ESTABLISHED 1439/sshd: root@pts
tcp6       0      0 ::1:25                  :::*                    LISTEN      1077/master
tcp6       0      0 :::22                   :::*                    LISTEN      987/sshd

如果服务端不关闭连接进程,超时时间到了会自动断开释放资源的

拿http协议举例

以上就是一个完整的请求:建立连接--》发送--》响应--》关闭

连接,三次握手,连接协议,连接状态,数据传输和确认,四次分手

连接是连接,请求是请求

先用连接,才会有应用层协议的传输过程

3.传输控制层

应用层想发送协议,得先建立连接,就需要到传输控制层,传输控制层的协议有tcp、udp

TCP:面向连接的、可靠的传输层控制协议

什么叫做连接?双方资源的开辟 ---》就得先三次握手建立连接

SYN 标志位,用S表示

ACK 确认包,用 . 表示(一个点)

第一次握手,客户端--》服务端:S

第二次握手,服务端--》客户端:S. (发出去不能保证客户端一定收到,所以还得一个确认)

第三次握手,客户端--》服务端:.

三次握手走完之后,双方会开辟一块内存,建立一个队列,netstat中看到的那个本地队列和远端队列,双方传输的内容就放这块内存中,程序到这来拿

什么叫面向连接:经过三次握手之后,在双方内存当中开辟队列等一系列资源的连接

什么叫可靠:通过确认的方式来得到传输的确认,就是一定传输给了对方

4.什么是连接池,并发和连接的关系

建立连接的连接应该是哪个学术名词代替?

连接就是socket,学术名词就是套接字、插座插头 (连接一定是有双方的)

socket不是ip port,而是二个ip port(双方),也就是四元组:ip port ip port

socket的目标是具备唯一性

PORT区间:0~65535

两台主机A和B,A的程序想连接B的tomcat,tomcat port是80,固定的,那理论上可以建立多少个socket

理论上是65535,因为port最多只能65535

此时B上再起一个tomcat 90,A还能不能与tomcat 90 建立连接?能的,也是理论上最多65535

socket具备唯一性,双方ip port唯一

四元组一定对应到队列,因为程序只能是通过队列读写的,而不是直接和对方进行传输

传输过程只是把数据放到了本机的队列中,从队列中传输,由内核空间去调度进程

从用户空间到内核空间的系统调用,对队列的操作,是一系列的IO读写操作

IO有BIO、NIO,就是内核对程序读取队列的反馈过程

应用层想发送数据,得先到传输控制层建立连接,走完三次握手之后,双方开辟资源,有了资源才能叫连接

5.什么是三次握手和四次分手 (网络层)

客户端 服务端 哪一方想先分手都可以

为什么握手是三次,分手是四次,因为socket是双向的,要双方都确认断开才能断开,所以一方会多回复一次是否确认断开。

客户端想FIN了,服务会端先问是否确认FIN,此时还在传数据的,还得等数据传输完,传输完后服务端回复FIN,最后客户端回复ACK确认断开连接

喝啤酒理论:不用喝一瓶跑一次小卖部,而是一次买一箱带回去,喝的时候从箱子拿,不用每次都跑小卖部,而这个箱就是buffer

IO中有各种buffer IO,减少程序到内核的系统调用,就是程序把需要操作很多数据一次从队列拿回来放入buffer中,然后用的时候从buffer读取就行了,而不是用一点到队列中读取一点,减少调用流程

网络层主要是两个概念:ip、route

ifcfg-eth0:interface接口程序 cfg 配置 ethernet以太网 0第一块网卡

IPADDR

NETMASK

GATEWAY

DNS

ip地址由网络号和主机号组成的

ipv4是点分字节的,一个字节由8个二进制位组成

IPADDR与NETMASK做二进制的与操作得到ip地址的网络号

网络号就是某个子网/局域网,主机号就是这个子网中的第几台机子

ip地址是为了寻址用的,那数据传输需要确认从哪个网卡出发去?就得用到路由

[root@localhost ~]# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.10.1    0.0.0.0         UG    100    0        0 ens33
172.17.0.0      0.0.0.0         255.255.0.0     U     0      0        0 docker0
192.168.10.0    0.0.0.0         255.255.255.0   U     100    0        0 ens33

目标可达 网关,全为0就不需要下一跳 掩码 配置文件
意思是通过配置文件能够连接到目标网络
第一行:ens33配置网络,也就是本机,通过下一跳192.168.10.1可以直连任何网络


[root@localhost ~]# route -n # 路由规则就是ifcfg配置文件里面的配置生成的
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.10.1    0.0.0.0         UG    100    0        0 ens33
172.17.0.0      0.0.0.0         255.255.0.0     U     0      0        0 docker0
192.168.10.0    0.0.0.0         255.255.255.0   U     100    0        0 ens33
[root@localhost ~]# ping www.baidu.com
PING www.baidu.com (14.215.177.38) 56(84) bytes of data.
64 bytes from 14.215.177.38 (14.215.177.38): icmp_seq=1 ttl=55 time=19.1 ms
64 bytes from 14.215.177.38 (14.215.177.38): icmp_seq=2 ttl=55 time=11.2 ms
64 bytes from 14.215.177.38 (14.215.177.38): icmp_seq=3 ttl=55 time=18.3 ms
64 bytes from 14.215.177.38 (14.215.177.38): icmp_seq=4 ttl=55 time=12.0 ms

外网通信解析:

在连接访问baidu中,通过dns解析得到baidu.com的ip,拿这个ip与路由表中的掩码做与运算,

如果得到的网络号与目标网络相同,那就是网络能通的

如上拿14.215.177.38与第一条路由表规则的掩码也就是0.0.0.0做与运算,得到0.0.0.0,跟前面Destination

是相同的,那只有把数据包交给192.168.10.1就可以连通baidu.com


内网通信不需要下一跳地址,直接交换机就行


6.什么是网关,什么是下一跳(链路层)

网络层只是找到了下一跳,如何把数据包发给下一跳还需要涉及到链路层

ip地址只能放端点的(源端、目标端)

中间传输的是节点,不能用ip地址,只能用mac

[root@localhost ~]# arp -an
? (192.168.10.1) at 00:50:56:c0:00:02 [ether] on ens33

发出去的数据包要封上下一跳的mac地址、目标端点的ip地址、目标端点进程端口号

arp在TCP/IP模型中属于IP层(网络层)协议,在OSI模型中属于链路层协议

arp协议即地址解析协议,是根据IP地址获取物理地址的一个TCP/IP协议。它可以解决同一个局域网内主机或路由器的IP地址和MAC地址的映射问题。

mac地址是烧在网卡的芯片上的,唯一的

由IP地址和掩码完成网络规划,由网卡烧录的mac地址完成下一跳的通信

需要从客户端访问到服务端,中间经过路由器R和运营商ISP,那包的封装如上,目标IP一直都是S-IP,没有变化的,变化的是中间节点的MAC,因为下一跳是用MAC通信的。

IP地址是端到端的,与中间传输节点无关,下一跳是由中间节点的mac地址通信的,可以说整个互联网通信是由下一跳支撑起来的,下一跳这个概念很重要。下一跳 在程序概念中就是链表,存在链路层

端点:数据包起点和结束的点,IP地址只出现在端点

节点:数据包跳跃点,MAC地址出现在节点,每跳一次,换一下MAC地址,因为节点换了

NAT分为SNAT、DNAT

各层是如何通信的?

客户端

应用层:先建立连接,调传输控制层

传输控制层:为了建立连接,先要完成三次握手,第一次握手包就会卡住,需要到网络层

网络层:查看路由表,找到下一跳网关,再找链路层

链路层:拿网络层得到的下一跳ip地址通过arp协议得到mac地址

物理层:通过以上得到目的ip地址、下一跳,mac地址发送数据包

服务端

客户端的三次握手第一次数据包得到传输控制层后,服务端回复ack确认包

再一次完成三次握手,完成三次握手后,建立队列,开始传输内容

LVS 四层负载均衡服务器 (第四层是传输控制层、tcp/ip)

nginx 七层负载均衡服务器(四层也可以) (第七层是应用层、http/https、url负载)

LVS不会和客户端建立三次握手,nginx会和客户端建立三次握手

四层的不会建立握手,七层的会,四层负载均衡器转发速度快,七层可以根据url和路径做更细粒度的转发负载

负载均衡服务器不是业务服务器,它就是发客户端请求分发给不同的服务端

四层负载均衡服务器就是偷窥狂(只看不碰)

客户端的数据包先是传输到LVS的传输控制层,因为只有在传输控制层才能看到数据包的状态和端口号,在依据LVS配置的规则,把这个带端口号的数据包丢给哪台服务器,最终是客户端和真实服务器建立三次握手

程序如何能读到url?先要建立三次握手

操作系统存在内核,且唯一,内核中有一个模块叫ipvs(国产章文松写的)

nginx能做四层转发,是因为本身nginx就是一个服务了,可以调用内核,nginx把转发丢给内核的ipvs模块,让其帮忙做四层转发

知道内核是做什么的?程序是做什么的?

lvs三种方式

DNAT,nat地址转换

DR,mac地址欺骗

T ,隧道

面试题

以上面试题主要还是通信到IO、网络到IO类的

知识点要分层分类掌握一些开放题,考的也是个人见解,看这个人的技术储备

测试三次握手

一台服务器192.68.10.20开启多个窗口模拟测试

先用nc服务起本机的9090端口

[root@localhost ~]# nc -l 192.168.10.20 9090

查看本机连接,可以发现nc的socket

[root@localhost ~]# netstat -antp
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 192.168.10.20:9090 0.0.0.0:* LISTEN 1493/nc
# 远端任何地址只要连接本机的9090端口,就把这个连接交给nc服务处理,此时socket是LISTEN状态的

开启抓包本机9090端口数据包:

[root@localhost ~]# tcpdump -nn -i ens33 port 9090

再开启一台192.168.10.30访问192.168.10.20 9090,查看状态

[root@localhost ~]# nc 192.168.10.20 9090

此时192.168.10.20的抓包有显示

[root@localhost ~]# tcpdump -nn -i ens33 port 9090
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ens33, link-type EN10MB (Ethernet), capture size 262144 bytes
14:58:47.221873 IP 192.168.10.30.44420 > 192.168.10.20.9090: Flags [S], seq 1368962930, win 29200, options [mss 1460,nop,nop,sackOK,nop,wscale 9], length 0
14:58:47.221908 IP 192.168.10.20.9090 > 192.168.10.30.44420: Flags [S.], seq 2817027668, ack 1368962931, win 29200, options [mss 1460,nop,nop,sackOK,nop,wscale 9], length 0
14:58:47.222232 IP 192.168.10.30.44420 > 192.168.10.20.9090: Flags [.], ack 1, win 58, length 0

这就是三次握手:S --》S.--》.

再查看连接状态

# 192.168.10.20的

[root@localhost ~]# netstat -antp
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 192.168.10.20:9090 192.168.10.30:44420 ESTABLISHED 1493/nc

# 192.168.10.30的

[root@localhost ~]# netstat -antp
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 192.168.10.30:44420 192.168.10.20:9090 ESTABLISHED 1481/nc

三次握手建立后,双方state才为establish

发送信息测试

客户端192.168.10.30发送测试信息

[root@localhost ~]# nc 192.168.10.20 9090
adf
123qwe

服务端192.168.10.20是能接收到信息的

[root@localhost ~]# nc -l 192.168.10.20 9090
adf
123qwe

并且前面多开的抓包窗口还会有显示信息

[root@localhost ~]# tcpdump -nn -i ens33 port 9090
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ens33, link-type EN10MB (Ethernet), capture size 262144 bytes
14:58:47.221873 IP 192.168.10.30.44420 > 192.168.10.20.9090: Flags [S], seq 1368962930, win 29200, options [mss 1460,nop,nop,sackOK,nop,wscale 9], length 0
14:58:47.221908 IP 192.168.10.20.9090 > 192.168.10.30.44420: Flags [S.], seq 2817027668, ack 1368962931, win 29200, options [mss 1460,nop,nop,sackOK,nop,wscale 9], length 0
14:58:47.222232 IP 192.168.10.30.44420 > 192.168.10.20.9090: Flags [.], ack 1, win 58, length 0
15:03:22.684868 IP 192.168.10.30.44420 > 192.168.10.20.9090: Flags [P.], seq 1:5, ack 1, win 58, length 4
15:03:22.684901 IP 192.168.10.20.9090 > 192.168.10.30.44420: Flags [.], ack 5, win 58, length 0
15:08:29.667359 IP 192.168.10.30.44420 > 192.168.10.20.9090: Flags [P.], seq 5:12, ack 1, win 58, length 7
15:08:29.667429 IP 192.168.10.20.9090 > 192.168.10.30.44420: Flags [.], ack 12, win 58, length 0

即三次握手完成后,开始客户端发送信息192.168.10.30.44420 > 192.168.10.20.9090,P就是PUT推送信息
192.168.10.20.9090 > 192.168.10.30.44420 返回点.就是服务端确认收到了信息
信息传输是双方的队列完成的,即连接状态中的各自Recv-Q Send-Q

客户端Send-Q --->服务端Rece-Q
服务端Send-Q --->客户端Rece-Q

三次握手完成后双方就会开辟资产建立信息传输的队列

队列为空内核有响应就是NIO

假如此时程序正在执行循环,很忙?客户端可不可以发送数据过来?可以的,客户端发送数据与程序无关,只是发送到内核的接收队列中Rece-Q,等程序不忙了再到Rece-Q中读取

程序的IO就只是程序到本机内核的队列过程的IO,有阻塞、非阻塞状态

数据永远先到达内核的内存空间,程序再择机(看程序模式)将数据拷贝到自己的程序空间

拷贝数据是成本,是需要线程在CPU上完成的,服务器上有很多CPU,程序即搬运数据又要使用数据,就涉及到线程池的使用

redis

worker永远是单线程的

版本6之前只有一个worker,没有线程池

6之后 读取,解析,响应,写入是多线程的

拷贝过程可以开启多线程,执行命令还是单线程

外界的连接,连接程序,首先都是先连接到操作系统的kernel

客户端到系统内核才是连接过程,内核到程序是IO过程

设置出了不同的线程,让它们未来跑在不同的CPU上,线程干不同的事

io therads跟io 多路复用器不是同一个东西

tcp连接,长短连接与通信状态有关,状态分为有状态和无状态

最后更新于 2025/6/21