第16章 非阻塞式I/O
来源:互联网 发布:iphone7移动数据开关 编辑:程序博客网 时间:2024/06/05 20:44
执行时间:
停等版本(完全阻塞) 》 select加阻塞I/O版本 》 fork多进程版本(Linux下多线程也应该差不多) 》 非阻塞I/O版本
非阻塞读写
#include "../Gnet.h"void do_client(int connfd){ char to[MAX_LINE], fr[MAX_LINE]; char *toiptr, *tooptr, *friptr, *froptr; int val, stdineof, maxfd, n, nwritten; fd_set rset, wset; val = fcntl(connfd, F_GETFL, 0); fcntl(connfd, F_SETFL, val|O_NONBLOCK); val = fcntl(STDIN_FILENO, F_GETFL, 0); fcntl(STDIN_FILENO, F_SETFL, val|O_NONBLOCK); val = fcntl(STDOUT_FILENO, F_GETFL, 0); fcntl(STDOUT_FILENO, F_SETFL, val|O_NONBLOCK); toiptr = tooptr = to; friptr = froptr = fr; stdineof = 0; maxfd = MAX(MAX(STDIN_FILENO, STDOUT_FILENO), connfd); while(1) { FD_ZERO(&rset); FD_ZERO(&wset); if(stdineof==0 && toiptr<&to[MAX_LINE])//标准输入->套接字 还有数据要发送&&缓冲区还有容量 FD_SET(STDIN_FILENO, &rset); if(friptr<&fr[MAX_LINE])//套接字->标准输出 缓冲区还有空闲 FD_SET(connfd, &rset); if(tooptr!=toiptr) FD_SET(connfd, &wset); if(froptr!=friptr) FD_SET(STDOUT_FILENO, &wset); select(maxfd+1,&rset,&wset,NULL,NULL); if(FD_ISSET(STDIN_FILENO, &rset)) { if((n = read(STDIN_FILENO, toiptr, &to[MAX_LINE]-toiptr)) < 0) { if(errno != EWOULDBLOCK) perr_exit("read error on stdin"); } else if(n == 0) { fprintf(stderr,"EOF on stdin\n"); stdineof = 1; if(tooptr == toiptr) shutdown(connfd, SHUT_WR); } else { fprintf(stderr, "read %d bytes from stdin\n", n); toiptr += n; FD_SET(connfd, &wset); } } if(FD_ISSET(connfd, &rset)) { if((n = read(connfd, friptr, &fr[MAX_LINE]-friptr)) < 0) { if(errno != EWOULDBLOCK) perr_exit("read error on socker"); } else if(n == 0) { fprintf(stderr, "EOF on socket\n"); if(stdineof) return; else perr_exit("server terminated prematurely"); } else { fprintf(stderr, "read %d bytes from socket\n", n); friptr += n; FD_SET(STDOUT_FILENO, &wset); } } if(FD_ISSET(STDOUT_FILENO, &wset) && ((n = friptr-froptr) > 0 )) { if((nwritten = write(STDOUT_FILENO, froptr, n)) < 0) { if(errno != EWOULDBLOCK) perr_exit("write error to stdout"); } else { fprintf(stderr, "wrote %d bytes to stdout\n", nwritten); froptr += nwritten; if(froptr == friptr) froptr = friptr = fr; } } if(FD_ISSET(connfd, &wset) && ((n = toiptr-tooptr) > 0)) { if((nwritten = write(connfd, tooptr, n)) < 0) { if(errno != EWOULDBLOCK) perr_exit("write error to socket"); } else { fprintf(stderr, "wrote %d bytes to socket\n", nwritten); tooptr += nwritten; if(tooptr == toiptr) { toiptr = tooptr = to; if(stdineof) shutdown(connfd, SHUT_WR); } } } }} int main(int argc, const char* argv[]) { int connfd; struct sockaddr_in server_addr; if(argc < 2) perr_exit("usage : client <IPaddress>"); connfd = Socket(AF_INET, SOCK_STREAM, 0); memset(&server_addr, 0, sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_port = htons(SERVER_PORT); inet_pton(AF_INET, argv[1], &server_addr.sin_addr); Connect(connfd, (struct sockaddr*)&server_addr, sizeof(server_addr)); do_client(connfd); return 0;}
多进程版本
#include "../Gnet.h"void do_client(int connfd){ char buf[MAX_LINE]; pid_t pid; if((pid = fork()) == 0) { while(Readline(connfd, buf, MAX_LINE) > 0) fputs(buf, stdout); kill(getppid(), SIGTERM); exit(0); } else { while(fgets(buf, MAX_LINE, stdin) != NULL) Write(connfd, buf, strlen(buf)); shutdown(connfd, SHUT_WR); pause(); }}int main(int argc, const char* argv[]){ int connfd; struct sockaddr_in server_addr; if(argc < 2) perr_exit("usage : client <IPaddress>"); connfd = Socket(AF_INET, SOCK_STREAM, 0); memset(&server_addr, 0, sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_port = htons(SERVER_PORT); inet_pton(AF_INET, argv[1], &server_addr.sin_addr); Connect(connfd, (struct sockaddr*)&server_addr, sizeof(server_addr)); do_client(connfd); return 0;}github:https://github.com/gongluck/unp-notes
阅读全文
0 0
- 第16章 非阻塞式I/O
- 第11章非阻塞I/O
- Unix网络编程代码 第16章 非阻塞式I/O
- UNIX网络编程卷1:套接字联网-第16章:非阻塞式I/O
- 非阻塞I/O
- 非阻塞I/O
- 非阻塞I/O
- 第8章 Linux设备驱动中的阻塞与非阻塞I/O
- linux驱动学习--第十四天:第八章 Linux 阻塞与非阻塞I/O
- UNP第十六章 非阻塞式I/O
- 第十六章 非阻塞I/O
- 非阻塞文件I/O
- 非阻塞I/O简介
- 非阻塞I/O笔记
- 非阻塞I/O简介
- 83-非阻塞 I/O
- 阻塞与非阻塞I/O
- 阻塞与非阻塞I/O
- 如何改进脚本下载
- maven 配置 ueditor
- Windows下Python开发环境搭建及Pycharm安装
- MySQL 8小时了
- 什么是Servlet容器
- 第16章 非阻塞式I/O
- lua错误:error:nesting of [[...]] is deprecated near
- 程序员注释神器
- 双11幕后超级英雄:新一代运维的价值
- wpf 后台动态添加控件(多个)
- 人工智能导论(1)——基本的决策树算法ID3
- 利用视觉和deep learning做自主导航
- 三级缓存
- redis性能优化好文