读《《图解TCP-IP》》有感

读《《图解TCP/IP》》有感

TCP/IP



最近几天读完《《图解TCP/IP》》,收获蛮多,记得上学时读stevens的《《TCP/IP详解》》时那是一个囫囵吞枣,没认真看也看不下去。等有时间再拜读下《《TCP/IP详解》》吧,估计能有不少共鸣。

现在觉得,要想比较透彻理解TCP/IP,还得需要有服务器编程经验,学校应该同时开设《socket编程》》相关课程,最好同一个老师教,可以串讲,不然光理论不实战就是花架子,而且也不容易真正理解TCP/IP协议。

TCP/UDP一览

只有较为透彻的理解了TCP/UDP才知道为啥TCP叫传输控制协议,UDP叫用户数据包协议。TCP在背后帮你做了很多事,连接管理,保存时序,超时重发,拥塞控制,流控;通过mss自动帮你做分片,以减少传输途中路由器分片消耗(IPV6路由器是不会分片的),这叫传输控制协议,突出“控制”二字。而UDP什么都不帮你做,不保证时序,不做超时重传,是需要上层协议来保证,也就是用户来写规则,这也是第一个U(user)的含义;同时UDP没有mss,所以一次性发送数据最好不要太多,以免分片导致性能损耗。那UDP为什么叫用户数据包协议呢,说到数据包就得说说TCP和UDP的面向连接和无连接了。

我们知道TCP是面向连接的,而UDP是无连接的,这就直接导致了TCP会通过三次握手连接服务器,如果服务器端口不对TCP是知道,但UDP不一样,压根不知道服务器段的情况,即使服务器不在线,客户端照样发送数据。

In [22]: import socket

In [23]: s=socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

In [24]: s.sendto("hello world",("127.0.0.1",9999))
Out[24]: 11

没有服务端,我们照样发送数据,sendto()照样返回,如果你之前不知道,这会让你大吃一惊,这也正说明了UDP不做数据包确认。

TCP传输的是流式数据,也就是说中间是没有分段的,这也就导致了我们常有的粘包问题,所以我们需要封包和解包,常见的都是字节长度+数据的方式,如websocket。也就是说我们接受一次,可能是对方多次发送后的数据集合,也可能是发送一次的部分数据,这都有可能,不能假设是哪种情况。这不经让我想起以前上学时写的简单socket客户端,服务器程序,都是一发一收,我们没封包解包不也正常吗?这就要说说Linux recv系统调用了。

int recv( SOCKET s, char FAR *buf, int len, int flags);

recv执行流程(来自网上)

1.recv等待s发送缓冲区数据发送完毕,如果中途出现网络错误,recv函数返回SOCKET_ERROR

2.recv检查s的接受缓冲区,如果接受缓冲区没有数据或者

正在接受数据,那么recv一直等待,直到把数据接受完毕。当接受完毕后,recv会把s接受缓冲区的数据copy到buf中(缓冲区数据可能大于buf长度,所以需要多次调用recv。recv仅仅是copy数据,真正接受数据是底层协议来完成的)

那这就好理解了,由于我们客户端通常是先send再recv,再发送完成之后recv会等待,而且我们数据量比较小,每次间隔比较大,所以有数据了,recv就返回了。当然这也是存在隐患的,发送数据大,一次recv可能接受不了,那就需要多次recv,这时就需要封包了,不然你怎么知道什么时候该返回。

就拿Http来说,服务端通过Content-Length和chunked编码来封包,让浏览器解析数据。当然http1.0其实Content-Length是非必须的,因为每次发送完数据后,服务端都会close,客户端recv会返回0,这时候也就知道数据结束了,也就是close作为了EOF标志,一帮下载都是通过这种方式,所以也不会有粘包。

而UDP是不会出现粘包的,接收肯定能完整接收到发送的数据,世界瞬间清净了,这也是UDP**数据包**的概念,一个一个的数据包,接收的都是完整的数据包。

校验和

TCP/IP中校验和校验算法都差不多,也就是所谓的

反码求和

过程如下

1.将校验和置为0

2.将数据转换为16字节整形,不足补零,求和(采用32位加法,将高16位和低16位相加,再将可能产生的进位与低16位相加)

3.和求反

最后发送者将校验和替换为求反的结果,将数据发给接受者,接受者忽略第一步采用同样算法,如果最后结果不为0,将丢弃该数据包。

手痒了一下,于是用golang模拟了下

//校验和算法
//对每16位(2字节)进行二进制反码求和,反码求和的意思是先对每16位求和,再将得到的和转为反码
func CheckSum(data []byte) uint16 {
    //padding 16
    all := len(data) / 2
    if all*2 < len(data) {
        all++
        data = append(data, 0)
    }

    u16 := (*[0xffff]uint16)(unsafe.Pointer(&data[0]))[:all]
    var sum uint32
    for _, u := range u16 {
        sum += uint32(u)
    }
    sum = (sum >> 16) + (sum & 0xffff) //把高位的进位,加到低八位
    sum += sum >> 16                   //前一步可能有进位
    return (uint16)(^sum)
}

func main() {
    check := make([]byte, 2)
    data := []byte("tcp/ip checksum test1")
    //首位作为校验和字段
    all := []byte(string(check) + string(data))
    sum := CheckSum(all)
    fmt.Println(all, sum)
    //校验和写入首位
    copy(all, (*[2]byte)(unsafe.Pointer(&sum))[:])
    fmt.Print(all, CheckSum(all))
}

结果:

[0 0 116 99 112 47 105 112 32 99 104 101 99 107 115 117 109 32 116 101 115 116 49] 22732

[204 88 116 99 112 47 105 112 32 99 104 101 99 107 115 117 109 32 116 101 115 116 49] 0

我们发现最后的确是0,说明我们算法没问题,至于为什么应该是0,小伙伴们想想就知道了。

TCP序列号与滑动窗口

下面说说TCP的seq,ack,在双方通信时seq开始是随机生成的,

假设A开始seq100,ack 1,发送数据size 100

通信 seq ack size
A->B 100 1 10
B->A 200 111 0
A->B 111 201 1000
B->A 201 1112 0

1.A->B 初始随机seq 100,ack 1,发送数据10字节

2.B->A 初始睡觉seq200,告诉A下一个发送111,前面的数据都收到了,由于B只是回应包 size 0

3.A->B A收到B的回应,看到ack为111,知道前面的10个自己都已经成功发送了,所以seq为111,发送1000个字节,并回应B下一个开始发送201

4.B->A ack为1000+111+1,告诉A下次从1112开始发送

只要对方回应了ack,那么就代表ack之前的数据都已经成功接收了,这是对方就可以把自己缓冲区的对应数据给清空了,不然需要保存以待重传。由于每次都单项传输,吞吐量有点低,所以TCP引用了滑动窗口,也就是在没有明确收到ack之前可以连续发送w个包,w就是滑动窗口的大小。由于引用了滑动窗口,有些ack丢失也没有关系,只要收到了后续的ack确认就代表之前的数据都已经成功接收了。

CSMA/CD

通信专业的对CSMA/CD肯定都不陌生,我发现老师特别喜欢说这玩意,但我以前始终不明白这玩意有啥用?其实CSMA/CD是用于共享网络的,也就是通过hub或同轴电缆等连接的总线型或星型拓扑结构,因为这东西我们基本都没见过(过时了),由于需要冲突检查所以是半双工通信。当交换机出来时,CSMA/CD就被淘汰了,通过交换机的端口转发实现了全双工通信。不知道是当初老师的问题还是我太弱,现在才明白应用场景。现在的无线也是半双工的,是CSMA/CD的改良版,叫CSMA/CA。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-12-12 21:45:48

读《《图解TCP-IP》》有感的相关文章

读&lt;反欺骗的艺术&gt;有感

月初收到了csdn寄来的书<反欺骗的艺术 ---- 世界传奇黑客的经历分享>. 之后就把书放床头, 每天晚上看上一会.直到今天, 才看完了这本书.挺有感触的. 之所以当初选择看这本书, 完全是被作者吸引来的.凯文·米特尼克((Kevin David Mitnick,1963年-),出生于美国洛杉矶,有评论称他为"世界头号黑客".他在15岁时就破解北美空中防务指挥系统成功,在他16岁时就被逮捕,他也因此而成为了全球第一名网络少年犯.)而如今, 这位历史上最令FBI头痛的计算机

一本好看的书————《反欺骗的艺术——世界传奇黑客的经历分享》

??      參加了csdn举办的活动,我有幸得到了这本书--<反欺骗的艺术--世界传奇黑客的经历分享>.该书的作者可谓大名鼎鼎(以前臭名昭著),他叫米特尼克,号称世界头号黑客.以前有着"显赫的战功",以前是历史上最令FBI头痛的计算机顽徒之中的一个.刚刚拿到这本书的时候,觉得这是一本写黑客供方技术的书籍.细致读了几页发现书中讲了黑客技术中"人的因素".的确,眼下的技术的发展趋势,让我们越来越重视技术本身.而一个个残酷事实告诉我们,现实生活中安全问题是

《反欺骗的艺术》读后感

为了配合CSDN的读书送书活动,在收到此书后第一时间就翻阅起来,正好利用3天假期时间进行了阅读并写下这篇读后感,假期也因此变得充实起来. 书的全名为<反欺骗的艺术--世界传奇黑客的经历分享>,原书的作者是有世界第一黑客之称的米特尼克,而译者为我们所熟知的潘爱民博士,从作译者的强大阵容来看,相信这本书的质量一定上乘. 当我刚拿到书的时候,看到这本书的书名--<反欺骗的艺术>,觉得有点茫然,不知道这本书究竟是讲什么方面的内容,而当我看了序言以及里面的"故事"的时候,

《反入侵的艺术——黑客入侵背后的真实故事》书评

说是书评,但限于本人词穷,表达能力也有限,叫读后感或许更好一些. 一. 前言简介 凯文·米特尼克(Kevin David Mitnick),世界范围名声最大,影响最高的黑客,没有之一. Mitnick也许就是黑客的代名词.美国司法部仍然指责他为"美国历史上头号电脑犯罪通缉犯".他的所作所为被记录在两部好莱坞电影当中:<Takedown>和<Freedom Downtime>. 15岁时,Kevin Mitnick用打工赚的钱买了一台计算机,当他"闲逛&

我读经典(6):读《文明之光》有感

什么是文明?如果突然问大家这个问题,那么你可能会不知如何回答,感觉这是一个只可意会但不可言传的概念. 在新书<文明之光>中,吴军老师为我们带来了答案.继<浪潮之巅>和<数学之美>之后,吴军老师又出力作<文明之光>,将世界各地的主要文明为我们一一呈现和讲解.整套书现在出了第一册和第二册,加起来一共有16章.在这16章中,作者基本按照时间的顺序,从最古老的古埃及文明讲起,一直到美苏在航天方面的竞争为止,为大家展示了一幅生动有趣的历史画卷.全书文笔流畅.语言优美.

读《何谓文化》有感

一.文化到底是什么? 最近在看余秋雨先生写的<何谓文化>,虽然自己也没有什么文化,但是感觉还是从中学到了一点东西,想要记录下来,.也让我开始思考一些生活中的文化. 既然说何谓文化,那就需要对文化来做一个定义,余秋雨先生的定义是:文化,是一种包含精神价值和生活方式的生态共同体.它通过积累和引导,创建集体人格. 这个定义里面有几个关键词语,分别是精神价值.生活方式.集体人格.我们经常会听到这样一个词语,文化差异,可是这个文化差异的直接体现就是在精神价值和生活方式上.经常会听到不少跨国婚姻,因&qu

读《软件随想录》有感

今天拿到Joel的<软件随想录>,读了一个章节,章节题名--我的第一次BillG审查. 这个章节中,Joel讲述了他在微软任职"excel"Program Manager时的经历.这里说到的BillG审查,说的就是比尔盖茨会审查报告.众所周知,比尔是个程序员出身的Boss,在微软中一直扮演的就是教父级的人物.但是好像看来这个BillG审查有点事必躬亲的味道. 今天,我们已经反复地通过各种论点来支撑了,一个Boss事必躬亲必然会导致其他职业的无能.但是Bill为什么还要审核,

我读经典(4):读《打造Facebook》有感

我第一次听说Facebook,是在用了国内的人人网很久之后.从上大学到研究生毕业,我几乎每天都要上人人网,发发日志.照片,看看其他同学有什么动向等等.个人感觉人人网使用起来非常的方便,拉近了人与人之间的距离,比QQ舒服多了. 某一天,我读到了一篇文章,主题是有关人人网的.文章里面说,人人网是中国的Facebook.这时,我便对Facebook产生了兴趣,接着上网去百度了一把,才知道它是全球最大的社交网络,于2004年2月4日正式上线,其主要创始人为美国哈佛大学的辍学生马克·扎克伯格(很有意思,比

知物由学 | 基于DNN的人脸识别中的反欺骗机制

"知物由学"是网易云易盾打造的一个品牌栏目,词语出自汉·王充<论衡·实知>.人,能力有高下之分,学习才知道事物的道理,而后才有智慧,不去求问就不会知道."知物由学"希望通过一篇篇技术干货.趋势解读.人物思考和沉淀给你带来收获的同时,也希望打开你的眼界,成就不一样的你.当然,如果你有不错的认知或分享,也欢迎通过邮件([email protected])投稿. 以下是正文: 本文作者:ArturBa?maga,YND的AI专家. 想象一下,只需使用脸部即可解

第8周读书笔记-读《编程珠玑》有感

读<编程珠玑>有感 <编程珠玑>(后文简称<珠玑>)在序章中就开宗明义地提出了两个问题:一个是如何对实际问题进行抽象,找出问题的独特性质.二是一个富有意思的小题目:"如何在1MB内存内对0~10^7内若干元素组成的集合内的整数进行排序(10s内)".一开始我想到的是归并排序,但是书中提出可以利用位图的位向量,不用考虑任何排序算法,只需要遍历两次即可,忽然就有茅塞顿开之感,从这个简单的例子中就可以对一些思想窥见一斑:位图数据结构.简单的设计.时间-空间