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

本文介绍了如何使用select函数实现IO多路复用,以解决IO阻塞导致的响应不及时问题。通过一个点对点聊天小程序的示例,详细讲解了客户端和服务器端的实现,涉及多线程、套接字和TCP连接。程序分为客户端和服务器两部分,先发起连接的一方作为客户端,另一方作为服务器,实现了两端的通信功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在网络编程中,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.源代码:

项目简介: 采用I/O复用技术select实现socket通信,采用多线程负责每个客户操作处理,完成Linux下的客户聊天室! OS:Ubuntu 15.04 IDE:vim gcc make DB:Sqlite 3 Time:2015-12-09 ~ 2012-12-21 项目功能架构: 1. 采用client/server结构; 2. 给出客户操作主界面(注册、登录、帮助和退出)、登录后主界面(查看在线列表、私聊、群聊、查看聊天记录、退出); 3. 客户可同时连接服务器进行自己操作; ##服务器端## 1. server.c:服务器端主程序代码文件; 2. config.h:服务器端配置文件(包含需要的头文件、常量、数据结构及函数声明); 3. config.c:服务器端公共函数的实现文件; 4. list.c:链表实现文件,用于维护在线用户链表的添加、更新、删除操作; 5. register.c:服务器端实现用户注册; 6. login.c:服务器端实现用户登录; 7. chat.c:服务器端实现用户的聊天互动操作; 8. Makefile:服务器端make文件,控制台执行make命令可直接生成可执行文件server ##客户端## 1. client.c:客户端主程序代码文件; 2. config.h:客户端配置文件(包含需要的头文件、常量、数据结构及函数声明); 3. config.c:客户端公共函数的实现文件; 4. register.c:客户端实现用户注册; 5. login.c:客户端实现用户登录; 6. chat.c:客户端实现用户的聊天互动操作; 7. Makefile:客户端make文件,控制台执行make命令可直接生成可执行文件client;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值