zoukankan      html  css  js  c++  java
  • 网络通信相关面试题

    TCP和UDP

    UDP,在传送数据前不需要先建立连接,远地的主机在收到UDP报文后也不需要给出任何确认。虽然UDP不提供可靠交付,但是正是因为这样,省去和很多的开销,使得它的速度比较快,比如一些对实时性要求较高的服务,就常常使用的是UDP。对应的应用层的协议主要有 DNS,TFTP,DHCP,SNMP,NFS 等。

    TCP,提供面向连接的服务,在传送数据之前必须先建立连接,数据传送完成后要释放连接。因此TCP是一种可靠的的运输服务,但是正因为这样,不可避免的增加了许多的开销,比如确认,流量控制等。对应的应用层的协议主要有 SMTP,TELNET,HTTP,FTP 等。

    三次握手

    第一次握手:主机A发送同步报文段(SYN)请求建立连接。

    第二次握手:主机B听到连接请求,就将该连接放入内核等待队列当中,并向主机A发送针对SYN的确认ACK,同时主机B也发送自己的请求建立连接(SYN)。

    第三次握手:主机A针对主机BSYN的确认应答ACK。

    四次挥手

    第一次挥手:当主机A发送数据完毕后,发送FIN结束报文段。

    第二次挥手:主机B收到FIN报文段后,向主机A发送一个确认序号ACK(为了防止在这段时间内,对方重传FIN报文段)。

    第三次挥手:主机B准备关闭连接,向主机A发送一个FIN结束报文段。

    第四次挥手:主机A收到FIN结束报文段后,进入TIME_WAIT状态。并向主机B发送一个ACK表示连接彻底释放。

    为什么连接的时候是三次握手,关闭的时候却是四次握手?

    TCP是全双工的,每个方向都要进行单独关闭。当一方完成数据发送任务后,发送一个FIN报文来终止这一方向的连接,这意味着不再发送数据,但是还可以接收数据,除非对方也发送了FIN报文。假设client端是主动发起方,当server端收到Client端的FIN报文后,知道它不再发送数据过来了。但server端自己还有数据没发完,不想立即关闭连接,所以只能先回复一个ACK报文,告诉client端,"你发的FIN报文我收到了"。server端等所有的数据都发送完了,然后发一个FIN+ACK报文给client端,client端收到后发送一个ACK报文给server端,server端收到了,然后才真正关闭了连接,故需要四步握手。

    四次挥手中的TIME_WAIT状态存在的理由

    理由之一:

    A不能保证最后的ACK能达到B, 所以, 还应该观望一段时间, 护送一段时间。 如果最后的ACK丢失, 那么B显然收不到,  B于是发起了重传FIN的操作, 此时如果A处于CLOSED的状态, 就没办法给对端发ACK了(实际是发RST), 呜呼哀哉。 所以A应该等一段时间, 这段时间就是所谓的TIME_WAIT, 比如, 等待一个RTT的时间(实际上, 考虑到如下的理由之二就知道, RTT可能不够, 用2MSL更靠谱)。

    所以, TIME_WAIT存在的理由之一是尽可能护送最后的ACK达到对端。

    理由之二:

    假设tcp连接是: A(1.2.3.4:8888)------B(6.7.8.9:9999), 这就是一个tcp四元组。 当tcp连接关闭后, 四元组释放。 后面的新连接可能会重用到这个四元组(有这个可能性), 那么问题就来了: 新四元组和旧四元组完全一致, 他们的网络包会混乱吗?   所以, 可以考虑这样一个机制: 让旧四元组对应的所有网络包都消失后(等一段时间), 才允许新四元组建立, 颇有点锁的味道。 那么这个等一段时间究竟是多久呢? 多久才合适呢? 在前面的文章中, 我们讨论过, 采用2MSL比较合适, 我个人认为, 把TIME_WAIT定义为2MSL只是一个通用的经验方法而已, 无法从理论上百分之百论证。

    所以, TIME_WAIT存在的理由之二是新旧四元组互不干扰。

    TCP报文头部

    1.源端口和目的端口,各占2个字节,分别写入源端口和目的端口;
    2.序号,占4个字节,TCP连接中传送的字节流中的每个字节都按顺序编号。例如,一段报文的序号字段值是 301 ,而携带的数据共有100字段,显然下一个报文段(如果还有的话)的数据序号应该从401开始;
    3.确认号,占4个字节,是期望收到对方下一个报文的第一个数据字节的序号。例如,B收到了A发送过来的报文,其序列号字段是501,而数据长度是200字节,这表明B正确的收到了A发送的到序号700为止的数据。因此,B期望收到A的下一个数据序号是701,于是B在发送给A的确认报文段中把确认号置为701;
    4.数据偏移,占4位,它指出TCP报文的数据距离TCP报文段的起始处有多远;
    5.保留,占6位,保留今后使用,但目前应都位0;
    6.紧急URG,当URG=1,表明紧急指针字段有效。告诉系统此报文段中有紧急数据;
    7.确认ACK,仅当ACK=1时,确认号字段才有效。TCP规定,在连接建立后所有报文的传输都必须把ACK置1;
    8.推送PSH,当两个应用进程进行交互式通信时,有时在一端的应用进程希望在键入一个命令后立即就能收到对方的响应,这时候就将PSH=1;
    9.复位RST,当RST=1,表明TCP连接中出现严重差错,必须释放连接,然后再重新建立连接;
    10.同步SYN,在连接建立时用来同步序号。当SYN=1,ACK=0,表明是连接请求报文,若同意连接,则响应报文中应该使SYN=1,ACK=1;
    11.终止FIN,用来释放连接。当FIN=1,表明此报文的发送方的数据已经发送完毕,并且要求释放;
    12.窗口,占2字节,指的是通知接收方,发送本报文你需要有多大的空间来接受;
    13.检验和,占2字节,校验首部和数据这两部分;
    14.紧急指针,占2字节,指出本报文段中的紧急数据的字节数;
    15.选项,长度可变,定义一些其他的可选的参数。

    TCP如何保证数据可靠性

    • 数据包校验
    • 超时重传机制
    • 应答机制
    • 对失序数据包重排序
    • TCP还能提供流量控制

    https://blog.csdn.net/guanghuichenshao/article/details/81916277
    https://blog.csdn.net/liuchenxia8/article/details/80428157

  • 相关阅读:
    Python模块笔记
    js日期
    js字符串
    js數字
    js對象構造
    js 錯誤
    js break和continue
    js條件結構和循環結構
    js運算符
    js函數
  • 原文地址:https://www.cnblogs.com/c-x-a/p/10950044.html
Copyright © 2011-2022 走看看