博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C++ 异步 IO(二) 服务器端多进程
阅读量:6901 次
发布时间:2019-06-27

本文共 2728 字,大约阅读时间需要 9 分钟。

通过多线程或多进程可以减弱阻塞IO的负面作用。

/* For sockaddr_in */#include 
/* For socket functions */#include
#include
#include
#include
#include
#define MAX_LINE 16384charrot13_char(char c){ /* We don't want to use isalpha here; setting the locale would change * which characters are considered alphabetical. */ if ((c >= 'a' && c <= 'm') || (c >= 'A' && c <= 'M')) return c + 13; else if ((c >= 'n' && c <= 'z') || (c >= 'N' && c <= 'Z')) return c - 13; else return c;}voidchild(int fd){ char outbuf[MAX_LINE+1]; size_t outbuf_used = 0; ssize_t result; while (1) { char ch; result = recv(fd, &ch, 1, 0); if (result == 0) { break; } else if (result == -1) { perror("read"); break; } /* We do this test to keep the user from overflowing the buffer. */ if (outbuf_used < sizeof(outbuf)) { outbuf[outbuf_used++] = rot13_char(ch); } if (ch == '\n') { send(fd, outbuf, outbuf_used, 0); outbuf_used = 0; continue; } }}voidrun(void){ int listener; struct sockaddr_in sin; sin.sin_family = AF_INET; sin.sin_addr.s_addr = 0; sin.sin_port = htons(40713); listener = socket(AF_INET, SOCK_STREAM, 0);#ifndef WIN32 { int one = 1; setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)); }#endif if (bind(listener, (struct sockaddr*)&sin, sizeof(sin)) < 0) { perror("bind"); return; } if (listen(listener, 16)<0) { perror("listen"); return; } while (1) { struct sockaddr_storage ss; socklen_t slen = sizeof(ss); int fd = accept(listener, (struct sockaddr*)&ss, &slen); if (fd < 0) { perror("accept"); } else { if (fork() == 0) { child(fd); exit(0); } } }}intmain(int c, char **v){ run(); return 0;}

1. 函数 rot13_char(char) 是用来转换字符的,{A,a}~{M,m} -> {N,n}~{Z,z} 其余符号不变

2. server监听端口并响应连接

  2.1 listener = socket(AF_INET, SOCKET_STREAM, 0) 创建套接字

  2.2 bind(listener, (sockaddr*)&sin, size(sin)) 绑定套接字到端口

  2.3 listen(listener, 16) 开始监听

  2.4 struct sockaddr_storage ss;

      socklen_t slen = sizeof(ss);

      int fd = accept(listener, (struct sockaddr*)&ss, &slen);

    每个fd标识响应的一个请求

  2.5 if (fork() == 0) {

child(fd); exit(0);}

    创建一个子进程,响应一个请求     

3. server端子进程的处理函数

  3.1 void child(int fd) 处理函数接口

  3.2 result = recv(fd, &ch, 1, 0); 从client端读取一个字符

         send(fd, outbuf, outbuf_used, 0); 发送一个字符串到client端

1. 创建子进程的过程

pid_t pid;     switch (pid = fork())     {     case -1:         perror("The fork failed!";         break;     case 0:         printf("I'm a child!";         system("touch /home/tom/abc.txt";         _exit(0);     default:         printf("Child's pid is %d\n",pid);     }

程序会输出default的内容,并且创建 abc.txt

原因是:创建子进程时,子进程复制了父进程的内容。子进程和父进程同时进入switch语句,但父子进程的pid并不同,因此进入不同的case。

 

转载于:https://www.cnblogs.com/zhouzhuo/p/3778617.html

你可能感兴趣的文章
zabbix-server安装部署配置
查看>>
终于解决 xUnit.net 测试中无法输出到控制台的问题
查看>>
【素数筛】分解质因数
查看>>
【ADT】队列的基本C语言实现
查看>>
NYOJ-1057 寻找最大数(三)(贪心)
查看>>
qt信号和槽
查看>>
第二章
查看>>
【Beta阶段】第六次Scrum Meeting
查看>>
nginx.conf配置文件详解
查看>>
maven使用问题汇总
查看>>
JavaScript事件详解-Zepto的事件实现(二)【新增fastclick阅读笔记】
查看>>
beautifulsoup 的children和descandants
查看>>
容器化微服务
查看>>
windows下redis 开机自启动
查看>>
python+selenium自动化测试-定位方式
查看>>
一致性Hash(Consistent Hashing)原理剖析
查看>>
Go并发编程实战 (郝林 著)
查看>>
android handler msg的使用 实现进度条
查看>>
485. 最大连续1的个数
查看>>
Software Testing Homework2
查看>>