问题一:请描述一个tcp三次握手
我从今用tcpdump抓过三次握手的包,然后wireshark去分析过。
1.客户端发送一个SYN包给服务器,并告诉服务器我的接受窗口的大小为14600字节,同时告诉服务器我的MSS大小为1460字节
2.服务器端收到SYC包后,发送ACK包给客户端,告诉客户端我的接受窗口大小为14600字节,同时告诉服务器我的MSS为1460字节
3.客户端收到ACK包后,发送ACK包给服务器,并告诉服务器我的接受窗口为14656,显然接受窗口变大了,连接建立
问题二:三次握手的过程中客户端和服务器端需要交互哪些信息
对方的接受窗口的大小和对方的MSS。
需要根据对方的接受窗口的大小,来调整己方的发送窗口的大小,已达到流量控制。调整的过程贯穿整个通信过程。
需要根据对方的最大报文长度(即每一个tcp包中所能携带有效负载的最大字节数),来调整己方的MSS,已确定如何分片。
问题三:MSS(最大报文长度)是怎么计算的
MSS是由MTU决定。当两台远程PC需要通信的时候,它们的数据需要穿过很多的路由器和各种各样的网络媒介才能到达对端,网络中不同媒介的MTU各不相同,就好比一长段的水管,由不同粗细的水管组成(MTU不同)通过这段水管最大水量就要由中间最细的水管决定。
以太网的帧结构DMAC+SMAC+Type+Data+CRC,DMAC+SMAC+Type为以太网帧头,一共14字节,帧尾的CRC校验码4字节,每个以太网帧都有最小的大小64bytes最大不能超过1518bytes,所以Data域最大是46字节到1500字节,Data域的最大值也叫做以太网最大传输单元叫做MTU。
UDP 包的大小就应该是 1500 – IP头(20) – UDP头(8) = 1472(BYTES)
TCP 包的大小就应该是 1500 – IP头(20) – TCP头(20) = 1460 (BYTES)
MSS=MTU-IP数据包包头的大小20Bytes和TCP数据段的包头20Bytes-TCP包头中会带有12字节的选项(时间戳)=1448
问题四:TCP/IP协议中分包与重组原理
tcp/ip七层协议由上至下tcp层是在ip层之上。
发包的时候,将数据加上应用层的协议,然后由应用程序将应用层buff的数据 copy到套接字发送buff,由内核控制数据加上tcp包头,然后是ip包头,最后才是以太网帧头。
收包的时候,数据先脱去以太网帧头,然后ip包头,最后才是tcp包头,然后才将数据从套接字接受buff copy到应用程序的buff中,当有说不定现在这个数据还有一些应用层协议,由应用程序将应用层协议包头脱去,才是真正的数据。
因为以太网有最大传输单元限制,一个tcp包所能携带的最大负载也是有限,超过这个值就需要对数据进行分片,也就是tcp/ip协议中的分包,那么分包是哪一层进行的?又如何分包?
发送方节点的网络层将数据分割成较小的数据片,同时对每一数据片安排一序列号,以便数据到达接收方节点的网络层时,能以正确的顺序重组,该过程即被称为排序。
tcp由于是可靠的传输协议,就算网络层某一个分包丢失,tcp也会重传。而udp是面向不可靠的传输协议,如果由网络层分包,某一个分包丢失,导致IP层组包发生错误,那么包就会被丢弃。接收方无法重组数据报,将导致丢弃整个IP数据报。所以在socket编程时,UDP数据包的大小最好小于限定值,tcp数据包的大小可以没有限制。
问题五:tcp包中的sequence number是什么含义
seq从0开始,发送第一个包。
seq为1标示,发送了一个包,且前面已经发送了一个字节。
seq为200标示,发送一个包,且前面已经发送了199个字节,下面从第200个字节开始发送。
所以seq相当于当前发送的包的起始字节数。
问题六:tcp和udp那个更容易产生网络碎片
tcp更容易产生网络碎片,UDP的每一个数据包,都是有包边界的,一个UDP数据包通常是一次发出去的,而TCP是面向字节流的协议,没有边界,一个tcp数据包并不一定会一次性发送出去,如果这段数据比较长,会被分段发送,如果比较短,可能会等待和下一次数据一起发送。
就具体函数而言:
用UDP协议发送时,用sendto函数最大能发送数据的长度为:65535- IP头(20) – UDP头(8)=65507字节。用sendto函数发送数据时,如果发送数据长度大于该值,则函数会返回错误。
用TCP协议发送时,由于TCP是数据流协议,因此不存在包大小的限制(暂不考虑缓冲区的大小),这是指在用send函数时,数据长度参数不受限制。而实际上,所指定的这段数据并不一定会一次性发送出去,如果这段数据比较长,会被分段发送,如果比较短,可能会等待和下一次数据一起发送。
所以同样的大小的数据发送,tcp可能需要发送更多的包,有效负载更低。
问题七:请描述一下一个tcp包收到的全过程
收包的时候,数据先脱去以太网帧头,然后ip包头,最后才是tcp包头,然后才将数据从套接字接受buff copy到应用程序的buff中,当有说不定现在这个数据还有一些应用层协议,由应用程序将应用层协议包头脱去,才是真正的数据。
问题五:进程和线程的区别
面试官觉得我回答有点太官方了,貌似听过无数次这种答案。
问题六:两个线程同时写和两个线程同时读,那个cpu访存的次数多
因为有缓存的存在,读同一个数据,由于程序局部性原理,会将数据缓存到cache中,下一次读直接读cache
请问你阅读过tcp源码吗?linux源码吗?mysql源码吗?
真心没看过