网络编程技术-----6、I/O复用实现并发服务器
一、实验要求
服务器:
服务器等待接收客户的连接请求,一旦连接成功则显示客户地址,接着接收客户端的名称并显示;然后接收来自该客户的字符串,对接收的字符串按分组进行加密(分组长度为个人学号,密钥为个人序号,分组不够补0),再将加密后的字符发回客户端;之后继续等待接收该客户的信息,直到客户关闭连接,服务器将每个连接的用户所发来的所有数据存储起来,当连接终止后,服务器将显示客户的名字及相应的所有数据。要求服务器具有同时处理多个客户请求的能力。
客户端:
客户首先与相应的服务器建立连接;接着接收用户输入的客户端名称,并将其发送给服务器;然后继续接收用户输入的字符,再将字符串发送给服务器,同时接收服务器发回的加密后的字符串并显示。之后,继续等待用户输入字符串,指导用户输入的是quit,则关闭连接并退出。
二、实验环境
- OS:kali
- 计算机语言:C
- 编译器:gcc
- IDE:VsCode
三、I/O复用涉及到的函数
- **FD_ZERO(fd_set *fdset);将指定的文件描述符集清空,在对文件描述符集合进行设置前,必须对其进行初始化,如果不清空,由于在系统分配内存空间后,通常并不作清空处理,所以结果是不可知的。**
- **FD_SET(fd_set *fdset);用于在文件描述符集合中增加一个新的文件描述符。**
- **FD_CLR(fd_set *fdset);用于在文件描述符集合中删除一个文件描述符。**
- **FD_ISSET(int fd,fd_set *fdset);用于测试指定的文件描述符是否在该集合中。**
- int select(int maxfd,fd_set rdset,fd_set wrset,fd_set exset,struct timeval timeout);用于在非阻塞中,当一个套接字或一组套接字有信号时通知你,系统提供select函数来实现多路复用输入/输出模型。
四、I/O复用实现流程
1、定义描述符集合,使用FD_ZERO()函数初始化描述符集合,然后将监听套接字描述符加入描述符集合中。
2、使用一个永真循环进行轮询。
3、在每次循环过程中,首先调用select函数将需要监听的描述符集合通知内核,然后使用FD_ISSET()函数判断监听套接字是否已经准备好,若已经准备好,调用accept函数获取已连接套接字,并将已连接套接字放进描述符集合中,然后更新已连接套接字个数和下一个循环调用select函数的第一个参数的值。接着使用在一个for循环中(循环参数为已连接套接字个数,相当于对每个已连接套接字都去查询是否已经准备好)FD_ISSET函数接着判断已连接套接字准备好,若准备完毕,则进行收发数据,若数据收发完毕,返回数据大小为0,则关闭已连接套接字,使用FD_CLR清理掉这个描述符在描述符集合中。以上完成后,则进入下一个循环,接着轮询。
五、实验代码
PS:由于MARKDOWN对代码支持太烂了,需要完整代码的请在下方的作者的github链接中下载或查看或者在下方留下你的邮箱私发也行!!!!
代码链接:https://github.com/windy-purple/I-O