您的位置:首页 > 理论基础 > 计算机网络

关于TCP的一些零散知识

2016-04-11 16:07 453 查看
一、 Socket能连接的最大端口号是多少?

答案是65536,也就是2的16次方。那么这个数值是怎么算出来的呢?看过下面的图,你就明白了



图1

上图是TCP首部的结构图,一个TCP首部固定部分只有20字节大小,前四个字节用来存储源端口和目的端口,各占两个字节,两个字节最大也就是2的16次方嘛。不过如果你在使用Socket时,端口号设置成了66000,也是可以连接的,但这不表明端口号真的超过了65536,仅仅是因为端口号大小“溢出”后,变成了66000-65536 = 464,真实打开的端口号是464

二、 TCP的三次握手到底是咋回事?

先看下面的两个小图





图2 图3

图2里,有6个标识位,都只占1位,图3里,是序号和确认号,说道序号,很多技术帖子里说是随机生成的,这是不准确的,当一端为建立连接而发送一个SYN包时,会选择一个初始序号--ISN,ISN随时间而变化,RFC 793 指出ISN可看作是一个32比特的计数器,每4ms加1,对这个序号,我们不必过多关心。

第一次握手:

方向: 数据由客户端发往服务端

标识位状态: SYN位是1,其他5个标识位是0

序号: 假设初始为J

确认号: 第一次握手时无效,不用管

这个,就是大家常说的SYN包

第二次握手:

服务端发现收到的包里,SYN标识位是1,他明白了,这个客户端想要和我建立连接,现在进行应答

方向: 服务端发往客户端

标识位状态,SYN,ACK是1,其他4个标识位是0

序号: 假设初始为K

确认号: J + 1 ,表示服务端已经收到了第一次握手时由客户端发来的SYN包

第三次握手:

客户端发现,收到的包里,SYN,ACK,都是1,那看来是服务端已经知道我想和他建立起连接了,接下来就确认一下,收到的包里,确认号是不是等于我第一次发给他的包里的序号+1 ,上述条件成立时,才会发一个ACK包给服务端

方向: 客户端发往服务端

标识位状态: ACK是1,其他5个标识位是0

序号: K

确认号: K+1 ,表示客户端已经收到了第二次握手时由服务端发来的ACK+SYN包

服务端收到第三次握手时由客户端发来的ACK包后,会检查确认号是不是等于自己第二次握手时发给客户端的ACK+SYN包里的序号+1,如果是,那么连接就建立起来了。这里要特殊说明的是,如果用wireshark抓包,你会发现,三次握手时,确认号都是从0开始的,但上面已经讲到,确认号是随机生成的,之所以会有这样的矛盾,那是因为wireshark考虑到用户的使用感受,确认号是进过处理的,显示出来的,是相对于随机数的偏移量,这样方便大家查看。

三、 TCP四次挥手

建立连接的时候,进行三次握手,断开连接的时候,进行四次挥手。

以客户端主动断开连接为例:

第一阶段:

第一次挥手,客户端发送一个FIN包(FIN标识位是1),序号为I,这是在告诉服务端,我打算关闭写通道了

第二次挥手,服务端收到第一步中发出的FIN包,关闭自己的读通道,发送一个ACK包,序号为I+1 ,表明我已经关闭读通道了,现在你可以关闭写通道了

客户端在收到了服务端发来的ACK包以后,关闭写通道,至此,四次挥手的第一阶段完成了。

第二次挥手中,服务端收到FIN包后,不会立马关闭自己的写通道,因为此时可能还有一些数据仍然在发送中,现在,服务端只是关闭读通道,此时,客户端仍然可以接收数据,服务端也可以发送数据

第二阶段:

第三次挥手,服务端写完了数据,发送一个FIN包,序号为J,告诉客户端,我打算关闭写通道了

第四次挥手,客户端收到第三次挥手中发来的FIN包,关闭自己的读通道,发送一个ACK包,序号为J+1,表明我已经关闭读通道了,现在,你可以关闭写通道了

服务端收到ACK包后,关闭自己的写通道

TCP是全双工的,因此每个方向必须单独关闭,你可能会注意到,建立连接的时候,是三次握手,而关闭的时候要进行四次挥手呢。建立连接的第二次握手过程中,服务端返回的是一个ACK+SYN包,也就是说确认包和SYN包是结合一起发回去的(syn和ack同时设置为1),因为实在是没必要分两次发送,而断开连接时,第二次挥手过程中,服务端只发回去一个ACK包,因为此时,仍然有些数据还没有发送给客户端,因此还不能发给客户端FIN包,一定要等到所有数据都发送结束了才能发送FIN包,就是这个原因,导致断开连接时是四次挥手。

四、 一个TCP分组最大可以发送多大的数

MSS,即Max Segment Size,这个东西标识了一个TCP分组能装载的最大数据,如果使用wireshark抓包,会发现,建立连接的两端,在最初发送自己的SYN包时,都会说明自己的MSS,此后,双方发送TCP分组数据时,就以最小的为数据大小上限进行发送。以太网数据帧最大是1518字节,其中有14个字节的帧头和4个字节的校验,这样还剩下1500个字节可用于发送数据。IP头最小20字节,TCP头最小20字节,这样,还剩下1460个字节可用于装载数据。但实际抓包发现,MSS可能会是1448,一个解释是TCP头里有12个字节的时间戳。图1中,有一段是选项,变长的,如果选项的长度不够,还要填充,确保TCP头部的长度是4个字节的倍数。TCP头部,有一段数据偏移,这部分有4位,最大为1111(15),这个数值的意思,TCP有多少个4字节。都是1,也就是15,表示TCP头部长度为60字节,因此,TCP头部最大为60字节。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: