43-使用 select 改进客户端
来源:互联网 发布:淘宝店铺买家监控软件 编辑:程序博客网 时间:2024/05/21 02:49
1. 程序路径
代码托管在 gitos 上,请使用下面的命令获取:
git clone https://git.oschina.net/ivan_allen/unp.git
如果你已经 clone 过这个代码了,请使用 git pull 更新一下。本节程序所使用的程序路径是 unp/program/echo/multiplexing_select_client
。
2. 回忆 select
2.1 函数原型
/* According to POSIX.1-2001 */#include <sys/select.h>/* According to earlier standards */#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);void FD_CLR(int fd, fd_set *set);int FD_ISSET(int fd, fd_set *set);void FD_SET(int fd, fd_set *set);void FD_ZERO(fd_set *set);
上面这些函数相信你不陌生,后面我们写程序会用到。
2.2 selece 的参数与返回值
(1)参数
- nfds 表示三个集合中最大描述符的值 + 1
- 后面三个 fd_set 集合分别表示监听哪种类型的事件,分别表示读事件,写事件和异常事件集合
- 最后一个参数是超时参数,可以为 NULL,表示永远等待
(2)返回值
- 小于 0,失败
- 等于 0,超时时间到
- 大于 0,发生了 IO 事件的个数
3. 改进客户端
在旧版本(processzombie 以其之前我们写过的程序)中,我们使用的客户端基本上都是这样:
void doClient(int sockfd) { // 客户端阻塞在标准输入上,一旦客户端收到了服务器的 FIN,也无能为力 while(fgets(buf, stdin)) { write(sockfd, buf); read(sockfd, buf); puts(buf); }}
缺点是它无法感知服务器进程发来的 FIN 段,现在改进如下(伪代码):
void doClient(int sockfd) { fds.add(STDIN_FILENO); fds.add(sockfd); maxfd = max(STDIN_FILENO, sockfd); while(1) { rfds = fds; // 只监听了标准输入和套接字 sockfd nready = select(maxfd + 1, &rfds, NULL, NULL, NULL); if (STDIN_FILENO in rfds) { if (fgets(buf, stdin) != NULL) { write(sockfd, buf); } else { break; } } if (sockfd in rfds) { if (read(sockfd, buf) == 0) { puts("peer closed"); break; } puts(buf); } }}
详细代码请参考 unp/program/echo/multiplexing_select_client/echo.cc
.
4. 运行结果
- 在 flower 机器上启动服务器
flower $ ./echo -s -h flower
- 在 sun 机器上启动客户端
sun $ ./echo -h flower
随意输入一些字符,服务器正常回射。接下来,将服务器子进程强制 kill 掉,出现图 1 的画面:
图1 服务器进程杀死后,客户端立即反应过来
图2 四次挥手,优雅断开
5. 总结
- 掌握在网络编程中使用 select
练习 1:将本程序中的 select 改为 poll.
练习 2:使用 select 改进服务器(将多进程改为单进程)
思考:这个程序有很严重的 bug,想想在哪里?
0 0
- 43-使用 select 改进客户端
- 使用select函数改进客户端/服务器端程序
- 使用select函数改进客户端/服务器端程序
- linux网络编程之socket(九):使用select函数改进客户端/服务器端程序
- linux网络编程之socket(九):使用select函数改进客户端/服务器端程序
- linux网络编程之socket(九):使用select函数改进客户端/服务器端程序
- 使用多线程改进网站客户端响应能力
- select 客户端
- Cocos2dx3.x使用socket创建服务端和客户端改进
- Cocos2dx3.x使用socket创建服务端和客户端改进
- 改进电子白板客户端程序
- ShoppingMall客户端改进计划
- FTP客户端(改进)
- IM 客户端C++版本改进。
- 使用select侦查客户端的连接以及接收客户端的数据
- winsock select模型客户端
- windows网络编程之select模型(改进)
- Android模拟器上使用NIO编写客户端中,使用select超时,立马返回0的问题
- 04.tooltip提示框插件,linkbutton按钮插件与progressbar进度条插件
- 使用maven发布idea中web项目到远程tomcat服务器
- 大小端问题
- Dagger2
- [UOJ #21]缩进优化
- 43-使用 select 改进客户端
- 学习笔记-POJ-1852蚂蚁问题
- 关于js面向对象的认识
- 删数问题
- Python简单实现基于VSM的余弦相似度计算
- 1018. 锤子剪刀布 (20)
- 逆向工程核心原理学习笔记(六):实战开辟新内存区域写入缓冲区跳转修改字符串
- Sass学习总结
- MyBatis基础操作