多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
## TCP-IP协议 **author:xiak** **last update: 2021-11-25 11:22:33** ---- [TOC=3,8] > 我们上层应用写的飞起,但总是出现奇怪的问题都是一脸懵,基础知识非常缺乏,尤其是做php和前端的,可能连tcp是什么都说不清楚 > 因为应用开发基本接触不到这些,都是给你封装好了,天高皇帝远,只知世间有 http 不知有 tcp > 我对 QUIC 大规模应用将会提高网络效率的论调持怀疑态度,TCP/IP 已经历了几十年的验证和修正,早已被验证过是稳定可靠的,可能我是过于保守了,但是不要忘了 tcp 协议的精髓是它的自治策略,在网络不稳定时它会牺牲个体的传输从而使整个网络更加稳定,而 QUIC 不是这样的,我不知道这种激进的策略在大规模网络下会出现什么问题,一切有待验证,并且新协议的推广和普及也不是一两天就可以做到的,即使被证明是有效的,也会在很长很长的时间内两者共同存在。 ---- ### OSI七层网络模型 / TCP/IP四层概念模型 ~~~ 5- Session 会话层 / 6- Presentation 表示层 7- Application 应用层 ↑↓ Binary byte: 应用数据: app首部 + 用户数据 (这只是为了界定业务数据的边界,粘包问题) #4 Transport 传输层 (tcp传输协议,port号) ↑↓ Segment - TCP段: tcp首部 + 应用数据 #3 Network 网络层 (ip地址) ↑↓ Datagram - IP数据报 (Packet - IP数据包分组): ip首部 + TCP段 Datagram: Packet{1, +} (fragment 分片) #2 Data Link 数据链路层 (网卡mac地址) ↑↓ Frame - 以太网帧: 以太网首部 + IP数据包 + 以太网尾部 length: 46 ~ 1500 #1 物理层 ↑↓ photon 光子 ~~~ ---- ### Wireshark 常用过滤规则 (源:数据发送方,目标:数据接收方) 数据链路层: 源mac地址 目标mac地址 网络层: 源ip 目标ip 传输层: tcp/udp 源端口 目标端口 应用协议层: http 请求/响应 头字段/内容 (响应是应用层的概念,对上层来说 其实是一次数据发送) ---- ### 七层网络模型 / 四层概念模型 <div class="table-box"><table border="1" cellspacing="0" cellpadding="0"><tbody><tr><td> <p align="center">OSI七层网络模型</p> </td><td> <p align="center"><a href="https://so.csdn.net/so/search?from=pc_blog_highlight&amp;q=Linux" target="_blank" class="hl hl-1">Linux</a> TCP/IP四层概念模型</p> </td><td> <p align="center">对应网络协议</p> </td></tr><tr><td> <p>应用层(Application)</p> </td><td rowspan="3"> <p>应用层</p> </td><td> <p>TFTP, FTP, NFS, WAIS</p> </td></tr><tr><td> <p>表示层(Presentation)</p> </td><td> <p>Telnet, Rlogin, SNMP, Gopher</p> </td></tr><tr><td> <p>会话层(Session)</p> </td><td> <p>SMTP, DNS</p> </td></tr><tr><td> <p>传输层(Transport)</p> </td><td> <p>传输层</p> </td><td> <p>TCP, UDP</p> </td></tr><tr><td> <p>网络层(Network)</p> </td><td> <p>网际层</p> </td><td> <p>IP, ICMP, ARP, RARP, AKP, UUCP</p> </td></tr><tr><td> <p>数据链路层(Data Link)</p> </td><td rowspan="2"> <p>网络接口</p> </td><td> <p>FDDI, Ethernet, Arpanet, PDN, SLIP, PPP</p> </td></tr><tr><td> <p>物理层(Physical)</p> </td><td> <p>IEEE 802.1A, IEEE 802.2到IEEE 802.11</p> </td></tr></tbody></table></div> ---- ### 扩展 [TCP 的那些事儿(上) | 酷 壳 - CoolShell](https://coolshell.cn/articles/11564.html) [TCP 的那些事儿(下) | 酷 壳 - CoolShell](https://coolshell.cn/articles/11609.html) > 但是TCP要解决一个很大的事,那就是要在一个网络根据不同的情况来动态调整自己的发包的速度,**小则让自己的连接更稳定,大则让整个网络更稳定。** > TCP的设计者觉得,一个伟大而牛逼的协议仅仅做到流控并不够,因为流控只是网络模型4层以上的事,TCP的还应该更聪明地知道整个网络上的事。 [TCP/IP四层模型和OSI七层模型_whmnirvana的博客-CSDN博客](https://blog.csdn.net/whmnirvana/article/details/76985001) [【工具-WireShark】网络HTTP抓包使用教程_Ric的博客-CSDN博客](https://lichong.blog.csdn.net/article/details/120820845) [通俗易懂TCP/IP(概述)](https://baijiahao.baidu.com/s?id=1679150230832085964&wfr=spider&for=pc) > 大物理学家费曼提出一个高效的费曼学习法,**即从问题入手,试着把问题都讲出来**,以教代学,**一旦你能把问题都讲清楚,便学会了。** [搞了半天,终于弄懂了TCP Socket数据的接收和发送,太难](http://www.360doc.com/content/20/0812/23/36242867_930032487.shtml) > 另一个反对排队的论点是,它使应用程序在连接的另一端(客户机)看起来很慢。客户机将看到它可以建立新的TCP连接,但是当它尝试使用它们时,服务器似乎响应非常慢。所以建议在这种情况下,最好是让新的连接失败,因为这样可以提供更明显的服务器不正常的反馈。 > 当用户态的进程实际调用文件描述符上的read(2)时,它会导致内核从其接收缓冲区中删除数据,并将该数据复制到此进程调用read(2)所提供的缓冲区中。 > > **接收读取时直接删除 read buffer 而不用等到 ack确认 发送完毕(ack本身也不需要再ack了啊),发送时 要等到 对方 ack 确认 到达才会删除 write buffer** 。 > 读语义:如果接收缓冲区已满,而TCP连接的另一端尝试发送更多的数据,内核将拒绝对数据包进行ACK。这只是常规的TCP拥塞控制。 > 写语义:如果写入队列已满,并且用户调用写入write(2)),则系统调用将被阻塞。 > 接收方 read buffer 满(说明应用程序处理能力过载),**不再接受数据, 不 ack 了,那么 发送方 write buffer 很快也就满了(等不到 ack 就不删除 write buffer)**,不能再发了。这算是一种 常规的TCP拥塞控制。 > > **发送能力会取决于对对方的接收能力,网络能相互自适应调节**,网络整体是自治的,最终整个网络会向健康的方向发展,通信效率趋于最大化,这是 tcp协议的魅力所在。这就像是交通一样,只要有秩序,就能减少拥堵,畅通无阻,都能平安到家。