Linux 复习 四

问:什么是IP地址

答:IP是网络互联的协议,是TCP/IP 网络层的协议,设计IP的目的是,提高网络的可扩展性,实现大规模的网络互通,Ip地址是网络上对于设备的识别

问:什么是端口?

答:唯一表示一个主机上的某个进程。

问:什么是网络字节序

答:网络传输的数据是一种字节流,在UDP/TCP/IP中,规定第一个接收到的字节放到高地址,也就是大端字节序,但是不同的主机存在不同的存储方式,为了统一,需要将数据进行网络字节序的转变。

问:常见的网络协议有哪些?

答:数据链路层:Wi-Fi    网络协议层:IP协议   传输层:TCP   UDP  应用层:HTTP  DNS  FTP SSH

问OSI  7层模型

  1. 物理层:利用传送介质,为数据链路层提供物理连接,实现比特流的透明传输
  2. 数据链路层:物理寻址,同时将比特流转换为逻辑传输路线(arp 协议,rarp协议)
  3. 网络层:控制子网的运行,逻辑编址,分组传输,路由选择
  4. 传输层:接收网络层的数据,必要时进行分割,达到端对端的连接,保证数据的可靠性
  5. 会话层:不同主机上的用户建立会话管理
  6. 表示层:将不同的数据格式进行转换,解析语法意义,加密解密,压缩解压缩等
  7. 应用层:为用户提供各种应用协议。

问:TCP/IP 4层模型?

问:什么是tcp协议?

答:tcp 是面向连接的可靠的流式服务

数据链路层:将数据封装成帧,加上报头和报尾,报头包括了目的MAC地址和源MAC地址

网络层:同过MAC地址找到对应的节点,通过arp 从Ip--MAC  或rarp 从MAC--IP 地址转换

TCP  编程流程

 server端socket()  ---   bind() ----listent()----accept()---recv()----send()----close()

 client 端  socket()--- connect() ---send()---recv()---close()

tcp 是面向字节流的,tcp有自己的缓冲,当应用程序传输的字节流太长,tcp就可以分短在传输

  • 源端口:标示报文 的返回接口     目的端口:指明接收主机的接口
  • 序号和确认号:是tcp传输可靠的关键部分,序号是本报文段发送数据组的第一个字节序号,每一个字节一个序号,例如一个报文段的序号为300,数据部分为100字节,则下一个报文段的序号为400,所以序号确定了tcp的有序性,确认号,即ACK 指明下一个期待收到的字节序号,表明该序号之前的数据,已经准确无误地收到,
  • 数据偏移/首部长度 tcp 头部长度不确定,若不包含任何子段是20字节,首部长度是指识了数据区在报文中的起始偏移值。
  • 控制位:URG  ACK  PSH  RST  SYN   FIN 
  • URG  :  紧急指针标记  1  有效,  0  无效
  • ACK  :确认序号标志    1  有效   ,0标示报文中不含字段确认消息,忽略确认号字段
  • PSH   :push标志   标示接收方收到数据,应该立即交给应用程序,而不是在缓冲区排队
  • RST   :重置连接标志   用于重置由于主机崩溃或者其他原因造成的错误连接,或者用于拒绝非法连接
  • SYN :同步序号,用于建立连接的时候
  • FIN: finish标志,标示没有数据发送了,关闭本方数据流
  • 滑动窗口:用来告知发送端接收端所能接受的缓冲的大小,用来控制发送端发送的速率,窗口大小是一个16位bit
  • 校验和:奇偶校验,对整个tcp 报头和数据进行校验  发送端计算和存储,接收端验证
  • 紧急指针:是发送端紧急发送给服务端数据的一种方式
  • 选项和填充:最常见的可选字段是最长报文大小,又称为MSS(Maximum Segment Size),每个连接方通常都在通信的第一个报文段(为建立连接而设置SYN标志为1的那个段)中指明这个选项,它表示本端所能接受的最大报文段的长度。选项长度不一定是32位的整数倍,所以要加填充位,即在这个字段中加入额外的零,以保证TCP头是32的整数倍。
  • 数据部分:TCP 连接 可以有数据部分,也可以没有

三次握手的过程

三次握手发生在connect()建立连接的时候

  1. 建立连接,客户端给服务器发送连接请求,发送SYN==1,序号seq==x, 然后客户端进入SYN_SEND,等待服务器确认
  2. 服务器收到SYN报文段,需要对SYN报文段进行确认,然后将确认号ACK=x+1 ,然后将ACK,和SYN==1 ,和序号seq==Y 发送给客户端,服务端进入SYN_RECV状态
  3. 客户端收到服务端发来的SYN+ACK报文,经应到报文ACK==Y+1,向服务端发送ACK 报文,完成3次握手,客户端和服务端都进入ESTABLISHED

问:为什么要三次握手?

答:因为防止已经失效的连接突然传送到服务端,而造成的资源浪费  例如:一个client向server发送了一次请求报文,但是在某个网络节点上滞留了长的时间,导致连接释放的某个时刻到达server端,而server端以为是一次新的请求,如果没有3次握手,此时服务端就和客户端建立建立,而客户端已经放弃了本次连接,也不发送数据,但是服务器一直等待数据,浪费了资源

问:那个阶段最容易受到攻击?

答:第二个阶段,当客户端伪造了大量的ip地址,然后给服务器发送SYN 请求,当服务器接受到SYN请求时,对SYN 进行确认,由于IP无效,服务器 会多次从发ACK 确认,确收不到客户端的第三次确认,导致服务端的未连接队列沾满,浪费了资源,使得正确连接无法继续,直到到达重传次数上限,或者超时时间,才会放弃这个攻击连接

问:解决办法?

  1. 缩短Timeout的时间,但是有可能因为网络拥塞导致正常连接失败
  2. 当未完成序列超过一半时,释放系统资源
  3. 设置SYN cookie    当server端回复SYN+ACK时,不立即分配数据区,而是通过一种算法,求的一个cookie 放大hash表中,将这个cookie值作为序号加密发送,若短时间收到相同SYN报文,则拉黑IP

问:listen(int fd,int baklog)的第二个参数意义?

答:内核会为我们维护两个队列,已完成队列,和未完成队列,SYN队列就是未完成队列,放着没有完成3次握手的连接,而listen()的backlog时表示,已完成队列中等待accept()最大数目,不同系统数目会比backlog多一个。

问:connect()作用?如何防止connect()长时间阻塞?

答:发起连接,建立三次握手,将connect()设置为非阻塞,用select 或者poll 机制来检测

问: send()发送成功是否代表数据已经到了接受方的缓冲区?

答:send()返回为-1 ,表示失败,=0表示成功写入自己的发送缓冲区,不能表示已经到了对面的接受缓冲区  recv()函数  返回值表示已经接受到字节个数,=-1 失败,=0 表示对方关闭了连接

问:什么是TCP粘包?如何解决?

答:产生粘包原因:

  • TCP为了更高的提高效率,Nagle算法往往会收集足够的数据才发送 ,
  • 接收方不及时接收消息,导致多个数据被一次recv()
  • 发送端缓冲区大于网卡MTU时,会进行拆包

解决粘包问题

  • 关闭Nagle算法,使用TCP_NODELAY选项修改
  • 每条数据增加特定符号开始和结尾,但是要保证数据内容不要包含特定字符
  • 每一条数据前4位为该数据的长度,这样可以根据长度读取数据

问:如何查看缓冲区有多少数据未处理

答:netstat -natp

问:流量控制

答:流量控制就是有可能客户端发送消息太快,而客户端来不及接收,可能会造成数据的丢失,滑动窗口机制很容易的解决了对放的发送速率

   TCP 为每个链接维护了一个计时器,当一次滑动窗口为rwnd=400 意思是有400字节的缓冲,当发送方收到rwnd==0表示不能再发

问:拥塞控制

双发维护着一个拥塞窗口,拥塞窗口的大小取决于网络的拥塞程度,动态的变换,原则上只要网络不拥塞,就扩大一点,否则拥塞窗口就减少,

    1     慢开始:当开始发送数据的时候,由于不清楚网络的负荷情况,采取试探性的增加窗口的数值,防止造成网络拥塞。

  初始设置rwnd=1,开始试探的成倍增加数值,即从1 ---2   ----4----8.........  为了防止一直增大,还要增加一个状态变量ssthresh,当rwnd<ssthresh,启动慢启动算法,当rwnd>ssthresh,采取拥塞避免,当rwnd==ssthresh,两种算法都可以

   2      拥塞避免

  当rwnd 增加的一定标准,不再是成倍增加,而是加1,一旦判断为网络拥塞,无论是慢启动阶段还是拥塞避免阶段,把开始的状态变量ssthresh设置为最初的一半(不能小于2),然后将rwnd=1,从新开始慢启动

快重传和快恢复

快重传算法要求每次接收到数据后立即发出确认,

当收到m1 m2 ,但是m3 丢失,接收端不对发过来的m4 m5 进行处理,而是再发m2 的确认,这样发送端就知道m3丢失了,所以立即重传m3

快恢复

当收到3次重复确认时,将慢开始的状态变量减半,然后将rwnd设置为ssthresh的值,执行拥塞避免算法。

断开连接的四次挥手

任意一方执行close()函数时,开始执行4次挥手

  1. 主机1 设置seq的值  seq==X,向主机2发送fin报文段 fin==1,  此时主机1 进入FIN_WAIT_1的状态
  2. 主机2被动收到FIN报文,向主机一发送ACK确认号ACK=X+1  主机一进入FIN_WAIT_2的状态,主机2进入CLOSE_WAIT状态(此时处于半关闭状态)
  3. 主机2 向主机一发送FIN=1,自己的seq=z,  主机2 进入LAST_ACK 最后确认状态
  4. 主机1 收到主机2的FIN后, 发送ACK=z+1 ,然后进入TIME_WAIT状态,主机2 收到ACK 后断开连接,主机1 等待两个报文时间,正常关闭。

问:为什么要4次分手?

答:因为TCP 是面向连接的可靠的,字节流式服务,而且是全双工模式,因此每个方向都是单独进行关闭的,当一方发送FIN只是告诉这边没有数据流动了,但是另一方仍然可以发送数据,只要也发送FIN时,双方才停止数据交流

问:TIME_WAIT的作用?

答:如果主机一直接关闭,由于网络原因,主机二并没有收到最好的ACK确认,那么主机二在超时,从新发FIN 报文,而此时主机一已经关闭,找不到连接,因此需要2个报文时间等待。

     如果主机一直接关闭,然后又向主机2 发送一次新链接,假如两次端口号相同,网络中有上次遗留的数据,会被认为是新链接的数据,导致数据混杂。

 因此 TIME_WAIT保证让TCP报文有足够的时间识别和丢弃

猜你喜欢

转载自www.cnblogs.com/lc-bk/p/12376149.html