增加I/O多路复用的回射程序
来源:互联网 发布:消防三知四会四个能力 编辑:程序博客网 时间:2024/04/28 05:22
在上一版本的回射程序中,若服务器子进程被杀死,则客户端检测不到这一事件的发生。原因在于,子进程被杀死时,虽然发送了FIN给客户端套接字,但此时客户端进程是阻塞于等待标准输入上的,因此检测不到套接字的输入。解决办法就是使用I/O多路复用。如下图所示:
另一个问题:若输入是批量输入,则输入结束后,客户端检测到EOF,则客户端会关闭连接,而网络中还有其他请求和应答,则会发现输出比输入少的现象,如下图所示
当全部的9个请求发出后,则会关闭连接,而此时只有应答1被接收到,其他的会丢失。
解决办法就是请求全部发送后,只关闭套接字写的那端,不关闭读的那端,也即半关闭状态
为此,使用了select来进行I/O多路复用。程序如下:
客户端:
#include <stdio.h>#include <sys/socket.h>#include <netinet/in.h>#include <string.h>#include <stdlib.h>#include <sys/select.h>#include <sys/time.h>#define err_exit(m)\ {\ perror(m);\ exit(EXIT_FAILURE);\ }#define SERV_PORT 9877#define BUFSIZE 4096int max(int a, int b){ if (a > b) return a; else return b;}//客户端具体操作函数void str_cli(FILE *fp, int sockfd);int main(int argc, char **argv){ if (argc != 2) { printf("argument error\n"); exit(0); } int sockfd; struct sockaddr_in servaddr; int status; bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(SERV_PORT); inet_pton(AF_INET, argv[1], &servaddr.sin_addr);//将点分十进制IP地址转化为网络字节序的二进制地址 sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd == -1) err_exit("socket"); status = connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));//连接服务器 if (status == -1) err_exit("connect"); str_cli(stdin, sockfd); exit(0);}void str_cli(FILE *fp, int sockfd){ int stdineof = 0; int maxfdp1; fd_set set; int n; char buf[BUFSIZE]; FD_ZERO(&set); for (;;) { if (stdineof == 0) FD_SET(fileno(fp), &set);//若stdineof = 1, 代表输入已完成,不再监听该描述符 FD_SET(sockfd, &set); maxfdp1 = max(fileno(fp), sockfd) + 1; select(maxfdp1, &set, NULL, NULL, NULL);//使用select的I/O多路复用 if (FD_ISSET(sockfd, &set))//套接字可读 { if ((n = read(sockfd, buf, BUFSIZE)) == 0) { if (stdineof == 1) return ; //正常退出 else { printf("server terminated prematurely"); exit(1); } } write(fileno(stdout), buf, n); } if (FD_ISSET(fileno(fp), &set))//标准输入可读 { if ((n = read(fileno(fp), buf, BUFSIZE)) == 0) //为0,则表示输入结束 { stdineof = 1; shutdown(sockfd, SHUT_WR); FD_CLR(fileno(fp), &set); continue; } write(sockfd, buf, n); } }}
0 0
- 增加I/O多路复用的回射程序
- TCP回射程序(I/O复用 select)
- linux的I/O多路复用
- I/O多路复用的实现
- 多路复用I/O的优缺点
- (unix网络编程)tcp回射程序三:多路复用
- 简单的回射程序
- 多路复用I/O Epoll的简单使用
- I/O多路复用
- 多路复用I/O
- I/O多路复用详解
- i/o多路复用例子
- I/O多路复用
- i/o多路复用
- I/O多路复用
- i/o多路复用
- I/O多路复用详解
- I/O多路复用
- 听说2017你想写前端?
- windows C++ 通过UDP广播获取网络中所有设备ip地址
- 26: Add Two Numbers
- AWS EC2笔记
- 嵌入式远程机房数采监控报警系统
- 增加I/O多路复用的回射程序
- java synchronized详解--synchronized代码块
- boolan web Ex笔记 三 关于button以及部分CSS3属性
- 利用AFN请求网路数据时出错。(Assertion failure in -[AFHTTPRequestSerializer requestWithMethod:URLString:paramete)
- 一步一步实现直播和弹幕
- 有关javascript图片上传预览有两种方式
- building--构建者模式
- 解决dialog中嵌套EditText,自动弹出软键盘的问题
- 设计模式学习笔记三(行为型模式)