IO多路复用(select)多线程实现点对点聊天

在网络编程中,IO操作不止本地的read或write,还会有网络套接字上的read和write。这样的话就容易出现这个问题:

当你用fgets函数在等待本地的标准输入,这时IO输入操作会阻塞在这里等待输入。如果此时网络套接字上传来了数据(比如说关闭连接命令),由于你的IO被阻塞在fgets处,无法及时知道网络套接字上传来的关闭命令。当你从fgets处获得数据后,再处理网络套接字发来的关闭命令的话,就响应不及时。

当然,IO会在读的时候阻塞,比如当缓冲区没有任何数据的时候,read会阻塞;写也会阻塞,比如缓冲区填满了数据,这时再用write写的话就会阻塞;连接tcp也会阻塞,当等待accept的队列已满时,就会出现连接阻塞。所以,IO阻塞的情况是经常发生的。

因此,为了解决IO被一个操作阻塞而对其他操作响应不及时的问题,就提出了IO多路复用。

IO多路复用最简单的就是利用select函数啦。

函数原型:

#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>

int select(int nfds, fd_set *readfds, fd_set *writefds,  fd_set *exceptfds, struct timeval *timeout);

其中nfds是要监视的最大的文件描述符再加1,比如要监视标准输入(文件描述符为1),本地文件读(假设文件描述符为2),网络套接字读(假设文件描述符为3),则此时nfds = 3 + 1;

readfds,writefds, exceptfds是三个监视文件描述符集合。readfds是监视集合中的文件描述符是否可读,同理writefds 和 exceptfds分别监视集合中的文件描述符是否可写和是否异常。

timeout是定时器,如果在定时器规定的时间内select还没有发现已经准备好的(可读或可写或异常)文件描述符的话,就不再监视,直接返回。

具体select怎么用,请自己在linxu系统上man一下:man select

下面来说一下我用select写的点对点聊天小程序:

1.讲解:

该程序分为两部分,一部分是客户端程序,另一部分是服务器程序。之所以将这两部分合并成一个程序,是为了解决定向连接的问题——只能一端为服务器,另一端为客户端。将两部分合并后,先发起连接的一方就为客户端,被连接的一方为服务器。

2.源代码:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值