网络编程最详细的总结

 一、前置知识

1.1 Linux下文件描述符(fd)

Linux中,一切皆文件,网络设备(如网卡)也是属于设备文件,当我们将网络设备中的数据输入(Input)到内存 或者 程序把内存数据输出(Output)到网络设备,都需要先打开设备文件,打开设备文件就会拿到该文件的文件描述符(一个很小的整数),每个进程在内存中都有一个对应的进程控制块(PCB),PCB中保存着一份文件描述符表,文件描述符就是该表的索引,表中的每个表项都有一个指向已经打开文件的指针。

二、网络I/O模型

阻塞统一指调用的IO函数所在的进程/线程被阻塞

2.1 阻塞I/O模型(Blocking I/O,BIO)

阻塞I/O模型是指当应用程序调用一个I/O函数时,如果网络设备(如网卡)中的数据还没有准备好,操作系统内核无法从其缓冲区中读取数据,系统内核会一直等待数据准备就绪,然后从内核空间拷贝到用户空间,I/O函数返回成功。在阻塞I/O模型中,从client socket中读一次数据会发生一次recv/recvfrom系统调用,整个过程都是阻塞的。

具体来说

当应用程序调用一个I/O函数时,如read方法,这个方法会触发操作系统内核的一次recv/recvfrom系统调用。如果内核还未接收到远端数据,数据报没有准备好,那么读取数据的线程就会一直阻塞,直到远端发来数据报。如果内核已经接收到远端数据,数据报已经准备好,那么数据报就会被从内核复制到用户空间,这一过程也是阻塞的。

2.2、非阻塞I/O模型(Non-blocking I/O,NIO)

非阻塞I/O指的是当应用程序调用一个I/O函数时,如果网络设备(如网卡)中的数据还没有准备好,操作系统内核无法从其缓冲区中读取数据,操作系统不会一直等待,而是会立即返回一个错误码。在NIO中,程序员需要以轮询(循环)的方式反复尝试读/写文件描述符(socket的fd),直到操作成功。这种模型相对于BIO来说,可以避免在等待数据准备好的过程中浪费CPU时间,提高CPU利用率。

具体来说

在非阻塞I/O模型中,当应用程序调用一个I/O函数时,如read方法,如果数据报没有准备好,那么read方法会立即返回一个错误码,例如WOULDBLOCK错误码。然后,程序员可以再次调用read方法,继续尝试读取数据报。这个过程需要程序员通过循环来不断尝试读取数据报,直到数据报准备好为止。

需要注意的是,在非阻塞I/O模型中,由于数据没有准备好导致的错误通常是由应用程序自己来处理的。因此,程序员需要编写代码来处理这些错误,例如重新尝试读取数据报或者进行其他的操作。此外,非阻塞IO模型也需要程序员手动控制循环和等待的过程,因此相对于阻塞I/O模型来说更加复杂。

总之

非阻塞I/O模型相比于BIO而言,可以提高CPU利用率,避免在等待数据准备过程中浪费CPU时间,但需要程序员手动控制循环和等待的过程,更加复杂。

2.3、I/O多路复用模型

IO多路复用技术允许一个进程或线程同时处理多个文件描述符的I/O操作,而不是一个个处理它们,主要有三种方法实现IO多路复用。

2.3.1 select

在select方法中,进程需要定期轮询所有文件描述符的状态,以查看它们是否准备就绪进行读写操作,当一个fd就绪时,该fd就可以被注册的回调函数处理

步骤:

1、将需要监视的文件描述符添加到一个fd_set结构体中

2、调用select函数,传入fd_set结构体、表示超时时间的结构体、数组指针,用于存储被唤醒的文件描述符,

缺点:随着文件描述符增加,需要检查的fd状态也在增加

2.3.2 poll

在poll方法中,进程只需要询问系统哪些文件描述符已经就绪,而不是像select那样定期轮询所有文件描述符,当一个fd就绪时,该fd就可以被注册的回调函数处理

2.3.3 epoll

Linux特有的IO多路复用方法,epoll使用事件驱动的方式,只有当文件描述符状态发生变化时(例如数据可以读取或写入),才会通知进程,当一个fd就绪时,该fd就可以被注册的回调函数处理

总结

Select和poll都是早期的IO多路复用方法,随着文件描述符数量的增加,它们的效率会降低。

Epoll是Linux特有的IO多路复用方法,它使用事件驱动的方式,只有当文件描述符状态发生变化时才会通知进程,因此它在处理大量文件描述符时比select和poll更高效。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

罗啰萝在努力

如果这篇文章对你有帮助,望支持

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值