一天速读《Unix网络编程》(上):TCP/UDP/IP + select/poll/epoll

Unix网络编程里面的5种IO分类

  • 阻塞IO

  • 非阻塞IO

  • 信号驱动IO

  • IO复用模型

  • 异步IO

前四种都是同步IO,最后一种是异步的。(信号驱动IO因为数据从内核空间复制到用户空间的时候仍然会被阻塞,因此算也是同步的)。

  • 同步IO——导致请求进程阻塞(请求进程:调用IO API的那个进程)

  • 异步IO——不会导致请求进程阻塞

 

select等待某个事件的发生,或是新连接的建立,或是已有连接的数据、FIN或RST。

一般模型如下:https://www.cnblogs.com/zhchy89/p/8850048.html

初始化 (socket,bind,listen);
while(1)
{
  设置监听读写文件描述符 (FD_SET*);
  调用 select;
  如果是倾听套接字就绪 , 说明一个新的连接请求建立
  {
    建立连接 (accept);
    将accept返回的client fd加入到监听文件描述符中去 ;
  }
  否则说明是一个已经连接过的描述符
  {
    进行操作 (read 或者 write);
  }
}

select、poll、epoll的区别(忘了在哪篇博客上看的了)

  1. select函数在响应时,并不知道是哪个socket状态改变了,因此需要遍历列表,时间复杂度O(n),而且有连接上限(32位机1024,64位机2048);

  2. poll和select一样,也需要遍历列表(O(n)),但是对连接上限作出了改进,无连接上限(因为内部采用了链表实现)

  3. epoll对以上的缺点作出了改善,epoll是事件响应机制(event poll),在fd中,有指向响应函数的指针,因此时间复杂度只有O(1)。

  4. 除此之外, select,poll每次调用都要把fd集合从用户态往内核态拷贝一次,而epoll只要一次拷贝( 每次注册新的监听事件到epoll句柄中时)。


TCP

  • 面向连接

  • 面向字节流

  • 可靠性——当TCP向一端发送数据时,要求收到确认,如果没有收到确认,就会重传数据,并等待更长的时间。如果多次重传失败,才放弃重传。

  • 含有估算传输往返时间(RTT)的算法

  • 序列号。具有排序功能,保证数据按顺序到达,保证一份数据只会到达一次,不会在网络中多次复制后多次到达。

  • 流量控制——确保发送端发送的数据不会过于频繁,超过接收端的接收能力。通过通告窗口控制。

  • 拥塞控制

  • 是全双工的

PS:

【1】三次握手、四次挥手补充:

  1. 挥手时的第一个FIN可以和最后发送 大数据一起发送(某些情况下)。

  2. TIME_WAIT状态(主动断开方的最后一个状态)

            时长:2MSL(IP数据表能在网络中存活的最长时间MSL的两倍),一般为2min或4min

            存在的理由:为了把原来的连接里面的重复数据包都已经在网络中消逝。避免老的连接的数据影响新建立的连接(新老连接的IP和端口号相同,新的被称为老的连接到化身)。

  1. 如果服务器主机崩溃后不主动给客户端发消息,那么客户端不知道服务端的主机已经崩溃了

【2】拥塞控制通过UDP实现

 

 

 

UDP

  • 面向无连接(《Unix网络编程》8.11节中提到可以给UDP调用connect,但与TCP含义不同,是指这个UDP只能从特定的服务器端口(用户通过connect指定)收发数据,来自其他服务器的数据包将会被丢弃)

  • 面向数据报

  • 是全双工的

  • 与TCP相比,UDP不具备可靠性(不知道是否丢失、不会主动重传)、不具备排序能力、不具备流量控制的能力。

PS:

【1】其实“ping”命令的原理就是向对方主机发送UDP数据包,然后对方主机确认收到数据包,如果数据包是否到达的消息及时反馈回来,那么网络就是通的。

【2】UDP比起TCP避免了很多链接建立和终止链接所需要的开销。

【3】UDP编写的常见应用程序有:DNS、NFS、SNMP等

【4】由于UDP数据丢失,接收端可能会一直阻塞在等待数据返回的read上,一般的解决方案是设定超时时间。

 

 

 

其他:

【1】SCTP协议

  • 流控制传输协议

  • 与TCP和UDP并列

  • 全双工。能像TCP一样提供可靠性、排序、流量控制,能像UDP一样,面向消息。

  • 2000年提出,相对年轻,因此知名度没有那么广

 

【2】TCP中的RST包与RST攻击

RST包——RST表示复位,用来异常的关闭连接。(就像上面说的一样,发送RST包关闭连接时,不必等缓冲区的包都发出去(不像上面的FIN包),直接就丢弃缓存区的包发送RST包。而接收端收到RST包后,也不必发送ACK包来确认。TCP处理程序会在自己认为的异常时刻发送RST包。例如,A向B发起连接,但B之上并未监听相应的端口,这时B操作系统上的TCP处理程序会发RST包。)

RST攻击是指第三方伪造A或者B发送RST包或者SYN包(然接收方以为发送发异常主动强制关闭连接)

 

【3】拒绝服务型攻击

客户端给服务端发了个字节(不是EOF)之后就挂起了,服务端必须不断等待读取下一个字节。

解决方案:(1)使用非阻塞式IO;(2)开多线程;(3)对IO操作设置超时时间


其他参考资料:https://www.cnblogs.com/zhchy89/p/8850048.html

 

你可能感兴趣的:(操作系统学习笔记,其他学习笔记)