来源于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协议
分层解耦:每个层干自己的事情 图片.png
OSI7层模型
7 应用层
6 表示层
5 会话层
4 传输层
3 网络层
2 数据链路层
1 物理层

普通交换机只有两层:链路层、物理层
三层交换机/路由器有三层:网络层、链路层、物理层
图片.pngTCP/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 指定网卡

建立连接

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

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

  1. [root@localhost ~]# tcpdump -nn -i ens33 port 80
  2. tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
  3. listening on ens33, link-type EN10MB (Ethernet), capture size 262144 bytes
  4. 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
  5. 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
  6. 13:19:50.415795 IP 192.168.10.20.33966 > 14.215.177.38.80: Flags [.], ack 1, win 58, length 0
  7. 1.客户端33966向服务端80发送请求
  8. 2.服务端80回复同意请求
  9. 3.客户端向服务端80确认
  1. [root@localhost ~]# netstat -natp
  2. Active Internet connections (servers and established)
  3. Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
  4. tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 1077/master
  5. tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 987/sshd
  6. tcp 0 0 192.168.10.20:22 192.168.10.1:64042 ESTABLISHED 1403/sshd: root@pts
  7. tcp 0 0 192.168.10.20:22 192.168.10.1:64400 ESTABLISHED 1439/sshd: root@pts
  8. tcp 0 0 192.168.10.20:33966 14.215.177.38:80 ESTABLISHED 1513/-bash
  9. tcp6 0 0 ::1:25 :::* LISTEN 1077/master
  10. 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是转换最后换行符的

  1. [root@localhost ~]# echo "GET / HTTP/1.0\n"
  2. GET / HTTP/1.0\n
  3. [root@localhost ~]# echo -e "GET / HTTP/1.0\n"
  4. GET / HTTP/1.0

获取baidu主页

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

查看baidu主页内容

  1. [root@localhost ~]# cat <& 8
  2. HTTP/1.0 200 OK
  3. Accept-Ranges: bytes
  4. Cache-Control: no-cache
  5. Content-Length: 9508
  6. Content-Type: text/html
  7. Date: Sat, 12 Feb 2022 08:51:20 GMT
  8. P3p: CP=" OTI DSP COR IVA OUR IND COM "
  9. P3p: CP=" OTI DSP COR IVA OUR IND COM "
  10. Pragma: no-cache
  11. Server: BWS/1.1
  12. Set-Cookie: BAIDUID=48BC5A1AAD87DA6B1D60B0411F9F4349:FG=1; expires=Thu, 31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com
  13. Set-Cookie: BIDUPSID=48BC5A1AAD87DA6B1D60B0411F9F4349; expires=Thu, 31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com
  14. Set-Cookie: PSTM=1644655880; expires=Thu, 31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com
  15. 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
  16. Traceid: 164465588003728634989399221463304205787
  17. Vary: Accept-Encoding
  18. X-Frame-Options: sameorigin
  19. X-Ua-Compatible: IE=Edge,chrome=1
  20. <!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&amp;tpl=mn&amp;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&amp;sa=ire_dl_gh_logo_texing&amp;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端口也显示有新内容

  1. [root@localhost ~]# tcpdump -nn -i ens33 port 80
  2. tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
  3. listening on ens33, link-type EN10MB (Ethernet), capture size 262144 bytes
  4. 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
  5. 17:05:51.696545 IP 14.215.177.38.80 > 192.168.10.20.33972: Flags [.], ack 15, win 908, length 0
  6. 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
  7. 17:05:51.705921 IP 14.215.177.38.80 > 192.168.10.20.33972: Flags [.], ack 16, win 908, length 0
  8. 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
  9. 17:05:51.707421 IP 192.168.10.20.33972 > 14.215.177.38.80: Flags [.], ack 4073, win 73, length 0
  10. 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
  11. 17:05:51.707451 IP 192.168.10.20.33972 > 14.215.177.38.80: Flags [.], ack 5493, win 79, length 0
  12. 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
  13. 17:05:51.709235 IP 192.168.10.20.33972 > 14.215.177.38.80: Flags [.], ack 10473, win 99, length 0
  14. 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
  15. 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
  16. 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状态是关闭等待的

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

关闭exec进程

  1. exec 8>& -

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

  1. 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
  2. 17:05:51.709235 IP 192.168.10.20.33972 > 14.215.177.38.80: Flags [.], ack 10473, win 99, length 0
  3. 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
  4. 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
  5. 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
  6. 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
  7. 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了

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

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

拿http协议举例
以上就是一个完整的请求:建立连接—》发送—》响应—》关闭

连接,三次握手,连接协议,连接状态,数据传输和确认,四次分手
连接是连接,请求是请求
先用连接,才会有应用层协议的传输过程

3.传输控制层

应用层想发送协议,得先建立连接,就需要到传输控制层,传输控制层的协议有tcp、udp
TCP:面向连接的、可靠的传输层控制协议
图片.png
图片.png
什么叫做连接?双方资源的开辟 —-》就得先三次握手建立连接
SYN 标志位,用S表示
ACK 确认包,用 . 表示(一个点)
第一次握手,客户端—》服务端:S
第二次握手,服务端—》客户端:S. (发出去不能保证客户端一定收到,所以还得一个确认)
第三次握手,客户端—》服务端:.
图片.png
三次握手走完之后,双方会开辟一块内存,建立一个队列,netstat中看到的那个本地队列和远端队列,双方传输的内容就放这块内存中,程序到这来拿
图片.png
什么叫面向连接:经过三次握手之后,在双方内存当中开辟队列等一系列资源的连接
什么叫可靠:通过确认的方式来得到传输的确认,就是一定传输给了对方

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

建立连接的连接应该是哪个学术名词代替?
连接就是socket,学术名词就是套接字、插座插头 (连接一定是有双方的)
socket不是ip port,而是二个ip port(双方),也就是四元组:ip port ip port
socket的目标是具备唯一性
图片.png
PORT区间:0~65535
两台主机A和B,A的程序想连接B的tomcat,tomcat port是80,固定的,那理论上可以建立多少个socket
理论上是65535,因为port最多只能65535
图片.png
此时B上再起一个tomcat 90,A还能不能与tomcat 90 建立连接?能的,也是理论上最多65535
图片.png
socket具备唯一性,双方ip port唯一
四元组一定对应到队列,因为程序只能是通过队列读写的,而不是直接和对方进行传输
传输过程只是把数据放到了本机的队列中,从队列中传输,由内核空间去调度进程

从用户空间到内核空间的系统调用,对队列的操作,是一系列的IO读写操作
IO有BIO、NIO,就是内核对程序读取队列的反馈过程图片.png
应用层想发送数据,得先到传输控制层建立连接,走完三次握手之后,双方开辟资源,有了资源才能叫连接

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

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

为什么握手是三次,分手是四次,因为socket是双向的,要双方都确认断开才能断开,所以一方会多回复一次是否确认断开。
客户端想FIN了,服务会端先问是否确认FIN,此时还在传数据的,还得等数据传输完,传输完后服务端回复FIN,最后客户端回复ACK确认断开连接
图片.png
喝啤酒理论:不用喝一瓶跑一次小卖部,而是一次买一箱带回去,喝的时候从箱子拿,不用每次都跑小卖部,而这个箱就是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地址是为了寻址用的,那数据传输需要确认从哪个网卡出发去?就得用到路由

  1. [root@localhost ~]# route -n
  2. Kernel IP routing table
  3. Destination Gateway Genmask Flags Metric Ref Use Iface
  4. 0.0.0.0 192.168.10.1 0.0.0.0 UG 100 0 0 ens33
  5. 172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 docker0
  6. 192.168.10.0 0.0.0.0 255.255.255.0 U 100 0 0 ens33
  7. 目标可达 网关,全为0就不需要下一跳 掩码 配置文件
  8. 意思是通过配置文件能够连接到目标网络
  9. 第一行:ens33配置网络,也就是本机,通过下一跳192.168.10.1可以直连任何网络
  1. [root@localhost ~]# route -n # 路由规则就是ifcfg配置文件里面的配置生成的
  2. Kernel IP routing table
  3. Destination Gateway Genmask Flags Metric Ref Use Iface
  4. 0.0.0.0 192.168.10.1 0.0.0.0 UG 100 0 0 ens33
  5. 172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 docker0
  6. 192.168.10.0 0.0.0.0 255.255.255.0 U 100 0 0 ens33
  7. [root@localhost ~]# ping www.baidu.com
  8. PING www.baidu.com (14.215.177.38) 56(84) bytes of data.
  9. 64 bytes from 14.215.177.38 (14.215.177.38): icmp_seq=1 ttl=55 time=19.1 ms
  10. 64 bytes from 14.215.177.38 (14.215.177.38): icmp_seq=2 ttl=55 time=11.2 ms
  11. 64 bytes from 14.215.177.38 (14.215.177.38): icmp_seq=3 ttl=55 time=18.3 ms
  12. 64 bytes from 14.215.177.38 (14.215.177.38): icmp_seq=4 ttl=55 time=12.0 ms
  13. 外网通信解析:
  14. 在连接访问baidu中,通过dns解析得到baidu.comip,拿这个ip与路由表中的掩码做与运算,
  15. 如果得到的网络号与目标网络相同,那就是网络能通的
  16. 如上拿14.215.177.38与第一条路由表规则的掩码也就是0.0.0.0做与运算,得到0.0.0.0,跟前面Destination
  17. 是相同的,那只有把数据包交给192.168.10.1就可以连通baidu.com
  18. 内网通信不需要下一跳地址,直接交换机就行

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

网络层只是找到了下一跳,如何把数据包发给下一跳还需要涉及到链路层
图片.png
ip地址只能放端点的(源端、目标端)
中间传输的是节点,不能用ip地址,只能用mac

  1. [root@localhost ~]# arp -an
  2. ? (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地址完成下一跳的通信

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

IP地址是端到端的,与中间传输节点无关,下一跳是由中间节点的mac地址通信的,可以说整个互联网通信是由下一跳支撑起来的,下一跳这个概念很重要。图片.png下一跳 在程序概念中就是链表,存在链路层
端点:数据包起点和结束的点,IP地址只出现在端点
节点:数据包跳跃点,MAC地址出现在节点,每跳一次,换一下MAC地址,因为节点换了

NAT分为SNAT、DNAT

各层是如何通信的?
客户端
应用层:先建立连接,调传输控制层
传输控制层:为了建立连接,先要完成三次握手,第一次握手包就会卡住,需要到网络层
网络层:查看路由表,找到下一跳网关,再找链路层
链路层:拿网络层得到的下一跳ip地址通过arp协议得到mac地址
物理层:通过以上得到目的ip地址、下一跳,mac地址发送数据包

服务端
客户端的三次握手第一次数据包得到传输控制层后,服务端回复ack确认包
再一次完成三次握手,完成三次握手后,建立队列,开始传输内容
图片.png
图片.png
LVS 四层负载均衡服务器 (第四层是传输控制层、tcp/ip)
nginx 七层负载均衡服务器(四层也可以) (第七层是应用层、http/https、url负载)
LVS不会和客户端建立三次握手,nginx会和客户端建立三次握手
四层的不会建立握手,七层的会,四层负载均衡器转发速度快,七层可以根据url和路径做更细粒度的转发负载
图片.png

负载均衡服务器不是业务服务器,它就是发客户端请求分发给不同的服务端
四层负载均衡服务器就是偷窥狂(只看不碰)
客户端的数据包先是传输到LVS的传输控制层,因为只有在传输控制层才能看到数据包的状态和端口号,在依据LVS配置的规则,把这个带端口号的数据包丢给哪台服务器,最终是客户端和真实服务器建立三次握手

图片.png

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

操作系统存在内核,且唯一,内核中有一个模块叫ipvs(国产章文松写的)
nginx能做四层转发,是因为本身nginx就是一个服务了,可以调用内核,nginx把转发丢给内核的ipvs模块,让其帮忙做四层转发

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

lvs三种方式
DNAT,nat地址转换
DR,mac地址欺骗
T ,隧道

面试题

图片.png
以上面试题主要还是通信到IO、网络到IO类的
知识点要分层分类掌握图片.png一些开放题,考的也是个人见解,看这个人的技术储备

测试三次握手
一台服务器192.68.10.20开启多个窗口模拟测试
先用nc服务起本机的9090端口

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

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

  1. [root@localhost ~]# netstat -antp
  2. Active Internet connections (servers and established)
  3. Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
  4. tcp 0 0 192.168.10.20:9090 0.0.0.0:* LISTEN 1493/nc
  5. # 远端任何地址只要连接本机的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的抓包有显示

  1. [root@localhost ~]# tcpdump -nn -i ens33 port 9090
  2. tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
  3. listening on ens33, link-type EN10MB (Ethernet), capture size 262144 bytes
  4. 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
  5. 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
  6. 14:58:47.222232 IP 192.168.10.30.44420 > 192.168.10.20.9090: Flags [.], ack 1, win 58, length 0

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

再查看连接状态

  1. # 192.168.10.20的
  2. [root@localhost ~]# netstat -antp
  3. Active Internet connections (servers and established)
  4. Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
  5. tcp 0 0 192.168.10.20:9090 192.168.10.30:44420 ESTABLISHED 1493/nc
  6. # 192.168.10.30的
  7. [root@localhost ~]# netstat -antp
  8. Active Internet connections (servers and established)
  9. Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
  10. tcp 0 0 192.168.10.30:44420 192.168.10.20:9090 ESTABLISHED 1481/nc
  11. 三次握手建立后,双方state才为establish

发送信息测试

  1. 客户端192.168.10.30发送测试信息
  2. [root@localhost ~]# nc 192.168.10.20 9090
  3. adf
  4. 123qwe
  5. 服务端192.168.10.20是能接收到信息的
  6. [root@localhost ~]# nc -l 192.168.10.20 9090
  7. adf
  8. 123qwe
  9. 并且前面多开的抓包窗口还会有显示信息
  10. [root@localhost ~]# tcpdump -nn -i ens33 port 9090
  11. tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
  12. listening on ens33, link-type EN10MB (Ethernet), capture size 262144 bytes
  13. 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. 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
  15. 14:58:47.222232 IP 192.168.10.30.44420 > 192.168.10.20.9090: Flags [.], ack 1, win 58, length 0
  16. 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
  17. 15:03:22.684901 IP 192.168.10.20.9090 > 192.168.10.30.44420: Flags [.], ack 5, win 58, length 0
  18. 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
  19. 15:08:29.667429 IP 192.168.10.20.9090 > 192.168.10.30.44420: Flags [.], ack 12, win 58, length 0
  20. 即三次握手完成后,开始客户端发送信息192.168.10.30.44420 > 192.168.10.20.9090P就是PUT推送信息
  21. 192.168.10.20.9090 > 192.168.10.30.44420 返回点.就是服务端确认收到了信息
  22. 信息传输是双方的队列完成的,即连接状态中的各自Recv-Q Send-Q
  23. 客户端Send-Q --->服务端Rece-Q
  24. 服务端Send-Q --->客户端Rece-Q

图片.png
三次握手完成后双方就会开辟资产建立信息传输的队列
图片.png队列为空内核有响应就是NIO

假如此时程序正在执行循环,很忙?客户端可不可以发送数据过来?可以的,客户端发送数据与程序无关,只是发送到内核的接收队列中Rece-Q,等程序不忙了再到Rece-Q中读取
程序的IO就只是程序到本机内核的队列过程的IO,有阻塞、非阻塞状态
图片.png数据永远先到达内核的内存空间,程序再择机(看程序模式)将数据拷贝到自己的程序空间
拷贝数据是成本,是需要线程在CPU上完成的,服务器上有很多CPU,程序即搬运数据又要使用数据,就涉及到线程池的使用

redis
worker永远是单线程的
版本6之前只有一个worker,没有线程池
6之后 读取,解析,响应,写入是多线程的
拷贝过程可以开启多线程,执行命令还是单线程

外界的连接,连接程序,首先都是先连接到操作系统的kernel
客户端到系统内核才是连接过程,内核到程序是IO过程

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

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

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