TCP/IP 协议到底在讲什么?

Posted 车小胖谈网络

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了TCP/IP 协议到底在讲什么?相关的知识,希望对你有一定的参考价值。

斜体部分为读者提问

看了很久的Richard Steven著的TCP/IP协议卷一: 详解 感觉自己读起来十分吃力 该怎么学这个 TCP/IP协议到底是在讲些什么 了解了TCP/IP协议能做些什么 还请各位指教。

 

 

 

更新部分

一些读者让我推荐入门的教材,就是那种通俗易懂的教材。坦率地说,这种教材是不存在的,网络技术其实是有一定的门槛的,这个要有清醒的认识。

 

Steven这本书写的非常好,但对于初学者确实有点难了。那初学者怎么办?既然难了,那就去找一些基础的入门课程去学,比如去学学CCNA的教程,至少知道什么是冲突域、广播域、网卡的收发帧的过程、网络掩码、网关、ARP。

 

 

通俗地说,TCP/IP做为一个整体,和现代社会的物流/快递公司非常相似。快递公司做为用户的代理,全权负责一个包裹从出发地送到目的地,所有运输的细节都是快递公司的分内之事,用户只负责收发包裹即可。

 

TCP/IP也是网络通信里的物流公司,应用程序只要把需要传输的数据提交给TCP/IP,TCP/IP就可以把数据打包发到目的地,至于里面的传输细节应用程序也可以不关心,这样应用程序就可以从最底层的传输细节里解放出来,把更多的注意力放在应用程序数据本身的处理。

 

但无论网络工程师还是软件工程师,应花点时间研究TCP/IP协议本身,做为一个庞大的物流公司,TCP/IP内部又包含很多职能部门,比如IP专门负责在Internet上寻找目的地,并将包裹送到目的地。

 

读者会有疑问,既然IP可以将包裹送到目的地,那还要TCP干嘛?

 

如果把IP比做物流公司的卡车+司机,那么TCP就是物流公司的调度中心,如果物流公司/司机掉进河里,造成包裹丢失,TCP做为调度中心可以分析判断得出,然后启动应急机制,会重新安排新的卡车+司机运输客户包裹上路,直到收到接收方的物流公司的确认才罢休。

 

以上的场景唯一和现实生活中不同的是,真实生活中的包裹丢了就丢了,怎么重传?难道物流公司会变魔术,变一个出来不成?

 

但在TCP/IP协议通信中,用户的数据做一份copy是非常简单的,一旦发现丢失,直接由TCP这个调度中心重传就好。

 

 

 

 

正文

先来谈谈汽车行业,随着家庭轿车的普及,越来越多的人开始使用汽车,其中99%人可能只会开车,不会修理汽车,也不了解汽车内部构造(细节),但这并不影响我们使用汽车。


而对于汽车维修工程师,很显然要精通汽车的内部构造,非常资深的工程师可以通过汽车的声音来定位故障点,这依靠的是多年的经验。而对于初入行的年轻工程师,如果只是看汽车的维修手册,即使看千遍也不一定会维修汽车。经常去4S店看到维修工将受损严重的汽车大卸八块,有时还会有老师傅在边上指导,通过这些动手操作,加上师傅的指导,再去参考维修手册,要不了多久就会很熟练地维修汽车,这样的模式:动手 + 理论 + 师傅指导 同样也适用于计算机网络的学习。


对于99%用户也不需要懂计算机网络,电脑、手机可以自动上网,即使有什么问题,通过插拔线、重启电脑、重启无线路由器基本上可以解决90%以上的问题。但是做为一位网络专业人士,则需要精通计算机网络的工作原理,精通原理可以帮助非专业人士提供专业的服务。



回到问题本身,《TCP/IP协议》详解卷一,是一本很好的教材,但是光看书有用吗?效果很差,因为这本书有点难度的。不动手不会有感性认识,然后读者会被抽象的概念弄的越来越迷糊,觉得越来越无聊,最终扔掉书,因为我干过好多次,然后过段时间又捡起来…


既然光看书很无聊,那就动动手吧。那时工作在国企,公司网络和互联网隔绝,QQ也无法使用,于是我就按照 Visual C++教程编写了聊天小程序(基于TCP socket ),把这个小程序给楼下的同事,无聊的时候就聊聊天,比如什么时候去吃午饭,下班什么时候撤?在程序启动的时候我就开始抓包,想看看究竟聊天内容怎么封装?究竟几个包完成发送任务?


封装倒很简单,让我惊讶的是,一条消息竟然双向耗费9个包,百撕不得其解,不就是调用一次 connect()建立连接,调用一次send(),然后程序退出


TCP建立连接
于是就去翻书,这次有针对性,直接翻到TCP协议部分,只看TCP如何建立连接,发现建立连接需要三个包的交互,这个应该是connect()完成的。


TCP发送数据
然后看到自己的消息内容是一个包,对方没有数据,只有确认ACK,这是两个包,这个由 send () 触发。


TCP释放连接
然后系统自动退出,虽然我的程序没有调用什么函数,但是系统自动帮我调用了 close () 函数,于是又触发了TCP 关闭连接,这是四个包。

于是把这三个阶段包的交换加在一起:3 + 2+ 4 = 9 ,哦原来是这样啊,通过这个小程序,再有针对性地看书,觉得很有趣。


后来我又试试用UDP socket 编写聊天程序,直接调用一个函数Sendto() 就可以了(用IP访问),抓包一看,一个消息就是一个包,对方也没有确认,UDP就是加上一个封装头就出去了,不需要建立连接,自然也无需关闭连接。


后来工作需要编写一个仿真程序,模仿GPS接收设备给导航设备周期(100ms 一次)发送GPS经纬度信息。接口为以太网接口,导航设备有嵌入式操作系统,支持TCP/IP协议栈,有了以前的动手经验,我很快就编写出基于TCP socket 的仿真软件,工作也很正常,但是有时发送数据会有卡顿的现象,时快时慢,有时还会停止发送。于是开始分析网络,办公室网络是交换机口到墙壁,然后用HUB再分出更多的端口,让大家共享带宽。于是想到了 CSMA/CD机制,电脑工作在半双工模式,发送数据前需要监听网络,当网络繁忙时,大家一起竞争,所以会有很大的延迟。


于是又用UDP socket 编写了相同的软件,卡顿现象好多了,后来我分析因为UDP包没有自我约束机制,调用一次sendto() 函数就把数据给IP,IP给网卡,网卡有CSMA/CD机制,会等待,也许会有延迟,也许会因为冲突而丢弃重发、或线路质量差出现CRC错而丢弃,但我的程序不 care,依然会按照100 毫秒发送一组数据,所以我最终选择UDP来做传输机制,丢一组、或几组数据没有多少关系,只要能把经纬度数据传送过去就可以了。


写了这些故事想表达的是:学习协议一定要动手,最好是结合项目来实践,然后需要补充哪些理论,有针对性地去翻书,对于每一个陌生的协议,需要抓包分析,不要偷懒,一份耕耘,一份收获。

以上是关于TCP/IP 协议到底在讲什么?的主要内容,如果未能解决你的问题,请参考以下文章

TCP/ip 的三次握手 和 socket 是啥关系?

tcp ip协议笔记——简单介绍

OSI模型与TCP/IP的关系

关于TCP/IP学习的书籍

一分钟了解 TCP/IP 模型

什么是TCP/ IP协议?