来源于B站马士兵教育课程:https://www.bilibili.com/video/BV1cF411p7PM?spm_id_from=333.788.top_right_bar_window_custom_collection.content.click
从用户空间、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
<!DOCTYPE html><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"><meta content="always" name="referrer"><meta name="description"content="全球领先的中文搜索引擎、致力于让网民更便捷地获取信息,找到所求。百度超过千亿的中文网页数据库,可以瞬间找到相关的搜索结果。"><link rel="shortcut icon" href="//www.baidu.com/favicon.ico" type="image/x-icon"><link rel="search" type="application/opensearchdescription+xml" href="//www.baidu.com/content-search.xml" title="百度搜索"><title>百度一下,你就知道</title><style type="text/css">body{margin:0;padding:0;text-align:center;background:#fff;height:100%}html{overflow-y:auto;color:#000;overflow:-moz-scrollbars;height:100%}body,input{font-size:12px;font-family:"PingFang SC",Arial,"Microsoft YaHei",sans-serif}a{text-decoration:none}a:hover{text-decoration:underline}img{border:0;-ms-interpolation-mode:bicubic}input{font-size:100%;border:0}body,form{position:relative;z-index:0}#wrapper{height:100%}#head_wrapper.s-ps-islite{padding-bottom:370px}#head_wrapper.s-ps-islite .s_form{position:relative;z-index:1}#head_wrapper.s-ps-islite .fm{position:absolute;bottom:0}#head_wrapper.s-ps-islite .s-p-top{position:absolute;bottom:40px;width:100%;height:181px}#head_wrapper.s-ps-islite #s_lg_img{position:static;margin:33px auto 0 auto;left:50%}#form{z-index:1}.s_form_wrapper{height:100%}#lh{margin:16px0 5px;word-spacing:3px}.c-font-normal{font:13px/23px Arial,sans-serif}.c-color-t{color:#222}.c-btn,.c-btn:visited{color:#333!important}.c-btn{display:inline-block;overflow:hidden;font-family:inherit;font-weight:400;text-align:center;vertical-align:middle;outline:0;border:0;height:30px;width:80px;line-height:30px;font-size:13px;border-radius:6px;padding:0;background-color:#f5f5f6;cursor:pointer}.c-btn:hover{background-color:#315efb;color:#fff!important}a.c-btn{text-decoration:none}.c-btn-mini{height:24px;width:48px;line-height:24px}.c-btn-primary,.c-btn-primary:visited{color:#fff!important}.c-btn-primary{background-color:#4e6ef2}.c-btn-primary:hover{background-color:#315efb}a:active{color:#f60}#wrapper{position:relative;min-height:100%}#head{padding-bottom:100px;text-align:center}#wrapper{min-width:1250px;height:100%;min-height:600px}#head{position:relative;padding-bottom:0;height:100%;min-height:600px}.s_form_wrapper{height:100%}.quickdelete-wrap{position:relative}.tools{position:absolute;right:-75px}.s-isindex-wrap{position:relative}#head_wrapper.head_wrapper{width:auto}#head_wrapper{position:relative;height:40%;min-height:314px;max-height:510px;width:1000px;margin:0 auto}#head_wrapper .s-p-top{height:60%;min-height:185px;max-height:310px;position:relative;z-index:0;text-align:center}#head_wrapperinput{outline:0;-webkit-appearance:none}#head_wrapper .s_btn_wr,#head_wrapper .s_ipt_wr{display:inline-block;zoom:1;background:0 0;vertical-align:top}#head_wrapper .s_ipt_wr{position:relative;width:546px}#head_wrapper .s_btn_wr{width:108px;height:44px;position:relative;z-index:2}#head_wrapper .s_ipt_wr:hover #kw{border-color:#a7aab5}#head_wrapper #kw{width:512px;height:16px;padding:12px 16px;font-size:16px;margin:0;vertical-align:top;outline:0;box-shadow:none;border-radius:10px 0 0 10px;border:2px solid #c4c7ce;background:#fff;color:#222;overflow:hidden;box-sizing:content-box}#head_wrapper #kw:focus{border-color:#4e6ef2!important;opacity:1}#head_wrapper .s_form{width:654px;height:100%;margin:0 auto;text-align:left;z-index:100}#head_wrapper .s_btn{cursor:pointer;width:108px;height:44px;line-height:45px;padding:0;background:0 0;background-color:#4e6ef2;border-radius:0 10px 10px 0;font-size:17px;color:#fff;box-shadow:none;font-weight:400;border:none;outline:0}#head_wrapper .s_btn:hover{background-color:#4662d9}#head_wrapper .s_btn:active{background-color:#4662d9}#head_wrapper .quickdelete-wrap{position:relative}#s_top_wrap{position:absolute;z-index:99;min-width:1000px;width:100%}.s-top-left{position:absolute;left:0;top:0;z-index:100;height:60px;padding-left:24px}.s-top-left .mnav{margin-right:31px;margin-top:19px;display:inline-block;position:relative}.s-top-left .mnav:hover .s-bri,.s-top-left a:hover{color:#315efb;text-decoration:none}.s-top-left .s-top-more-btn{padding-bottom:19px}.s-top-left .s-top-more-btn:hover .s-top-more{display:block}.s-top-right{position:absolute;right:0;top:0;z-index:100;height:60px;padding-right:24px}.s-top-right .s-top-right-text{margin-left:32px;margin-top:19px;display:inline-block;position:relative;vertical-align:top;cursor:pointer}.s-top-right .s-top-right-text:hover{color:#315efb}.s-top-right .s-top-login-btn{display:inline-block;margin-top:18px;margin-left:32px;font-size:13px}.s-top-right a:hover{text-decoration:none}#bottom_layer{width:100%;position:fixed;z-index:302;bottom:0;left:0;height:39px;padding-top:1px;overflow:hidden;zoom:1;margin:0;line-height:39px;background:#fff}#bottom_layer .lh{display:inline;margin-right:20px}#bottom_layer .lh:last-child{margin-left:-2px;margin-right:0}#bottom_layer .lh.activity{font-weight:700;text-decoration:underline}#bottom_layer a{font-size:12px;text-decoration:none}#bottom_layer .text-color{color:#bbb}#bottom_layer a:hover{color:#222}#bottom_layer .s-bottom-layer-content{text-align:center}</style></head><body><div id="wrapper" class="wrapper_new"><div id="head"><div id="s-top-left" class="s-top-left s-isindex-wrap"><a href="//news.baidu.com/" target="_blank" class="mnav c-font-normal c-color-t">新闻</a><a href="//www.hao123.com/" target="_blank" class="mnav c-font-normal c-color-t">hao123</a><a href="//map.baidu.com/" target="_blank" class="mnav c-font-normal c-color-t">地图</a><a href="//live.baidu.com/" target="_blank" class="mnav c-font-normal c-color-t">直播</a><a href="//haokan.baidu.com/?sfrom=baidu-top" target="_blank" class="mnav c-font-normal c-color-t">视频</a><a href="//tieba.baidu.com/" target="_blank" class="mnav c-font-normal c-color-t">贴吧</a><a href="//xueshu.baidu.com/" target="_blank" class="mnav c-font-normal c-color-t">学术</a><div class="mnav s-top-more-btn"><a href="//www.baidu.com/more/" name="tj_briicon" class="s-bri c-font-normal c-color-t" target="_blank">更多</a></div></div><div id="u1" class="s-top-right s-isindex-wrap"><a class="s-top-login-btn c-btn c-btn-primary c-btn-mini lb" style="position:relative;overflow:visible" name="tj_login" href="//www.baidu.com/bdorz/login.gif?login&tpl=mn&u=http%3A%2F%2Fwww.baidu.com%2f%3fbdorz_come%3d1">登录</a></div><div id="head_wrapper" class="head_wrapper s-isindex-wrap s-ps-islite"><div class="s_form"><div class="s_form_wrapper"><div id="lg" class="s-p-top"><img hidefocus="true" id="s_lg_img" class="index-logo-src" src="//www.baidu.com/img/flexible/logo/pc/index.png" width="270" height="129" usemap="#mp"><map name="mp"><area style="outline:0" hidefocus="true" shape="rect" coords="0,0,270,129" href="//www.baidu.com/s?wd=%E7%99%BE%E5%BA%A6%E7%83%AD%E6%90%9C&sa=ire_dl_gh_logo_texing&rsv_dl=igh_logo_pcs" target="_blank" title="点击一下,了解更多"></map></div><a href="//www.baidu.com/" id="result_logo"></a><form id="form" name="f" action="//www.baidu.com/s" class="fm"><input type="hidden" name="ie" value="utf-8"> <input type="hidden" name="f" value="8"> <input type="hidden" name="rsv_bp" value="1"> <input type="hidden" name="rsv_idx" value="1"> <input type="hidden" name="ch" value=""> <input type="hidden" name="tn" value="baidu"> <input type="hidden" name="bar" value=""> <span class="s_ipt_wr quickdelete-wrap"><input id="kw" name="wd" class="s_ipt" value="" maxlength="255" autocomplete="off"> </span><span class="s_btn_wr"><input type="submit" id="su" value="百度一下" class="bg s_btn"> </span><input type="hidden" name="rn" value=""> <input type="hidden" name="fenlei" value="256"> <input type="hidden" name="oq" value=""><input type="hidden" name="rsv_pq" value="b9ff093e0000e419"> <input type="hidden" name="rsv_t" value="3635FYbdbC8tlWmudZmYaUnaucNe+RzTzNEGqg/JuniQU10WL5mtMQehIrU"> <input type="hidden" name="rqlang" value="cn"> <input type="hidden" name="rsv_enter" value="1"> <input type="hidden" name="rsv_dl" value="ib"></form></div></div></div><div id="bottom_layer" class="s-bottom-layer s-isindex-wrap"><div class="s-bottom-layer-content"><p class="lh"><a class="text-color" href="//home.baidu.com/" target="_blank">关于百度</a></p><p class="lh"><a class="text-color" href="//ir.baidu.com/" target="_blank">About Baidu</a></p><p class="lh"><a class="text-color" href="//www.baidu.com/duty" target="_blank">使用百度前必读</a></p><p class="lh"><a class="text-color" href="//help.baidu.com/" target="_blank">帮助中心</a></p><p class="lh"><a class="text-color" href="//www.beian.gov.cn/portal/registerSystemInfo?recordcode=11000002000001" target="_blank">京公网安备11000002000001号</a></p><p class="lh"><a class="text-color" href="//beian.miit.gov.cn/" target="_blank">京ICP证030173号</a></p><p class="lh"><span id="year" class="text-color"></span></p><p class="lh"><span class="text-color">互联网药品信息服务资格证书 (京)-经营性-2017-0020</span></p><p class="lh"><a class="text-color" href="//www.baidu.com/licence/" target="_blank">信息网络传播视听节目许可证 0110516</a></p></div></div></div></div><script type="text/javascript">var date=newDate,year=date.getFullYear();document.getElementById("year").innerText="©"+year+" Baidu "</script></body></html>
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连接,长短连接与通信状态有关,状态分为有状态和无状态