TCP-IP协议栈
连接
连接是一个逻辑概念,物理层面就是一个对象(Socket)代表着若干资源
多线程复用一个连接
需要保证并发的安全性,互斥地使用连接。
一个线程一个连接
连接数会很多
注意多线程复用连接和连接池复用连接是两个维度的概念。
多线程复用连接是多个线程互斥地使用连接,连接池复用连接是客户端使用完连接后并不销毁,而是将连接放回连接池,以供下一个请求访问使用。
演示
服务端:
|
|
客户端:
|
|
|
|
查看资源占用情况:
|
|
TCP/IP 协议栈
- 软件工程学中分层的目的是为了解耦
- https看似tcp/ip协议,实际上有点osi参考模型的影子,是否加密在表示层,token、证书的验证在会话层。
- 每一层都有各自的协议指导工作以及库函数辅助工作
- rpc自定义协议是在应用层自定义协议,比如嫌弃http协议低效自定义应用层协议,这一层协议是由程序员赋能出来的。
- 应用层以下是内核帮我们实现好的,对程序员透明。
应用层
模拟应用层通信
首先使用nc与服务器建立连接,这一步相当于应用层以下已经建立好连接,后面要做的就是在应用层与服务器根据应用层协议进行通信。
|
|
|
|
基于HTTP协议通信
|
|
回车
响应头 两个换行符 响应体(BODY)
再比如连接redis服务器
如上就是按照redis-cli和redis-server之间的协议进行交互。
TCP层
通过三次数据包的交互,开辟资源socket代表对方
连接 三次握手 四次挥手
为什么是三次的, 连接是双向的,服务端发送ack之后需要客户端给到一个确认
连接走通之后需要开辟资源 开辟内存空间接受队列 发送队列,用socket表示,连接是逻辑概念,资源是物理概念。
可靠的传输协议:确认机制,传输控制层发送确认,如果没确认则重传,一定次数后就算失败。
三次握手进行连接,确认机制保证了可靠的传输。
释放端口号 释放内存空间
socket 代表了应用层访问tcp层的sap(服务访问点),四元组(唯一性,ip:port + ip:port 唯一确认,区分每个socket对应关系)
之前jdk使用socket对象代表socket,通过socket对象获取独立的输入输出流。jdk7有了nio,使用channel表示socket,channel可读可写,再也不用获得独立的输入输出流了。跟linux中的文件描述符保持一致(0 1 2)。
ip:为了找到主机
port:为了找到运行在主机上的进程,进程映射
- 连接一台服务器的某个进程,客户端消耗多少个端口号 65535
- 连接一台服务器的某个进程,服务端消耗多少个端口号 1
- 连接两台服务器,消耗多少个端口号 2 * 65535
- 第一个问题,如何突破65535, 客户端增加一个网卡
jmeter就可以通过这种方式在单机情况下造成更多连接
端口号
服务端 确定的端口号,比如80
客户端 随机端口号 最多65535个
为什么断开连接需要四次挥手?
三次握手,建立了资源,断开连接就是释放资源
客户端发送FIN后, 接受队列得保留着,服务端发送FIN+ACK只是表示接受到了FIN信号,但是可能还会继续发送数据包
当服务端也发送FIN后表示不再继续发送数据包,客户端发送ACK,再等待一定时间后(TIME_WAIT 默认两个传送时间,防止对方让我重传)就可以释放资源了。服务端收到ACK同样等待一段时间后就可以释放资源。
任何一方都可以发起断开连接请求。
耳听为虚眼见为实,使用tcpdump抓包看一下这个过程
|
|
客户端使用curl 模拟三次握手,四次挥手过程
连接过程详情:
页面内容是1400+1381这么大, 分成两个数据包发送
最上面3次握手,中间内容传输,下面是4次挥手
1500个字节,抛开协议头大小,就是1400
tcpdump 可以使用-X
显示数据包详情
ddos 分布式拒绝服务
在全球抓一些肉鸡,给对方发第一个包,不发送最后一个确认包,消耗对方资源。一般是通过 规则数据库 特征抽取, 建立黑名单进行防范。
网络层
传输层产生的握手包如何发出去?
多个网卡, 从哪发出去 ip route
什么是ip?
|
|
ip由两部分网络号 和 序号 组成,ip和掩码与运算得到 网络号,网络号是由网卡eth0配置的,连到一个局域网,这台机器是这个局域网的第多少号(序号)机器,同一个局域网网络号不会变。同一个网络号的机器只需要经过交换机(第二层链路层)交换数据不通过路由器。
掩码
网关 下一跳, 大门
把世界所有的设备节点信息保存到内存 组成网络拓补结构,根据图计算最小路径?
使用另一种方式,不安全的传递机制,下一跳
路由器,route -n
得到路由表
172.17.0.1就是下一跳
ping www.baidu.com
,
数据包从哪发出去?
目标地址180.101.49.11路由表的掩码进行与运算,255.255.0.0 得到180.101.0.0没匹配上, 换成0.0.0.0 匹配上。所以172.17.0.1就是这个数据包的下一跳,也就是路由器的地址。
再比如ping局域网里的一台机器
和255.255.0.0与运算匹配上,下一跳是0.0.0.0,不需要网关不需要下一跳,网关直接转发出去就行。转发不走网关,公网就得走网关。
ip协议层做了两件事, ip协议中 数据包 目标ip 180.101.49.11, 并且选择下一跳(网关)172.17.0.1
链路层
如果没有链路层,得把世界所有的设备节点信息保存到内存 组成网络拓补结构,根据图计算最小路径。现在只需要记录下一跳的mac地址即可。
链路层协议arp
arp -d
是ARP协议中bai删除ARP缓存列表的命令,du可以删除所有的ARP缓存,也可以删除指定的ARP缓存。zhi
ARP协议是将目标IP地址dao映射为目标MAC地址的协议,其在协议上使用ARP请求及ARP应答报文来实现。例如arp -a命令是显示ARP缓存的命令命令,它可以显示电脑上所有的ARP缓存条目。
到链路层,既有传输层的端口号又有网络层的ip地址,还有链路层的mac地址(放的是下一跳的mac地址,由网关广播然后局域网中的各台进行设置)
端点间通信,数据包是在节点间传递,跳跃
每个三层设备都有自己的路由表,都存放着下一跳的mac地址
路由器的目标mac地址换成运营商的mac地址。目标ip地址不变,目标mac地址会变化,像是一个链表,所以叫链路层。
DNS 域名通过DNS转换为IP
mac地址全球唯一, 可以刷,只要在一跳之内mac地址唯一不重复即可。
如果没有目标mac地址,需要走arp协议请求mac地址。
|
|
会先请求下一跳mac地址,放入自己的arp 缓存列表中。
物理层
网卡的事情,电 波 光 ,信号
小结
多层映射,唯一路径
一个进程会线程创建一个socket
多个socket对应一个进程或一个线程 就是 多路复用器 epoll
应用层让内核创建一个连接,
传输层 握手包
网络层 下一跳的ip地址
mac层 下一跳的mac地址
物理层 电 光 波 信号
高并发 负载均衡
七层 ngix 基于反向代理的负载均衡,往后代的时候解决高并发,后面可以有几千台服务器。ngix 握手, ngix节点支持的连接数比tomcat多。
四层 LVS 不能破坏连接(一对资源)的原子性,握手还是客户端和服务端握手。LVS不握手 只负责数据包转发。
LVS 负责维护客户端和服务端连接的全声明周期,监控、偷窥、记事本。 负载均衡算法。
没有并发就没有juc、负载均衡,就不用考虑是每请求每连接还是连接复用,连接是否要加锁,连接池,是否要用threadlocal。
网络 分布式 微服务 服务治理 service mesh。
mmap RandomAccessFile