标签:并发服务器 网络编程 高并发 应用程序 include 网络服务
在做网络服务的时候并发服务端程序的编写必不可少。前端客户端应用程序是否稳定一部分取决于客户端自身,而更多的取决于服务器是否相应时间够迅速,够稳定.
常见的linux并发服务器模型;
多进程并发服务器
多线程并发服务器
select多路I/O转接服务器
poll多路I/O转接服务器
epool多路I/O转接服务器.
本次主要讨论多线程并发服务器模型:
使用多进程并发服务器时要考虑以下几点:
父进程最大文件描述个数(父进程中需要close关闭accpet返回的新文件描述符)
系统内创建进程个数(与内存大小相关)
进程创建过多是否降低整体服务性能(进程调度)
.server代码[实际开发中要特别注意函数调用返回值判断]
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <arpa/inet.h> #include <string.h> #include <signal.h> #include <sys/wait.h> #include <ctype.h> /* * 多进程并发服务器 * author: sea time 2016/06/18 */ #define SERV_PORT 9096 //服务器端口号 #define SERV_ADDR "10.10.101.102" //服务器ip地址 void wait_process(int num){ //回收子进程 while(0 < waitpid(0, NULL, WNOHANG)){ ; } } int main(int argc, char* argv[]){ pid_t pid; //创建进程使用 int lfd; //监听套接字 int cfd; //客户端套接字 struct sockaddr_in serv_addr; //服务器地址族结构体, 绑定使用 struct sockaddr_in clie_addr; //客户端地址族结构体,接收连接使用 socklen_t clie_addr_len; //客户端地址族大小,接收连接使用 char buf[BUFSIZ]; int n, i; //注册进程结束信号,回收结束的子进程 signal(SIGCHLD, wait_process); //创建监听套接字 //AF_INET: 指定ipv4 //SOCK_STREAM: 指定tcp //0: 函数会根据指定的类型来自动指定协议 lfd = socket(AF_INET, SOCK_STREAM, 0); //全部初始化为0 bzero(&serv_addr, sizeof(serv_addr)); //指定族:ipv4 serv_addr.sin_family = AF_INET; //指定ip地址并转换为网络字节序 inet_pton(AF_INET, SERV_ADDR, &serv_addr.sin_addr.s_addr); //指定端口号并转换为网络字节序 serv_addr.sin_port = htons(SERV_PORT); //绑定到监听套接字 bind(lfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)); //指定监听套接字并设置同时连接上限 //SOMAXCONN: 系统默认为128 listen(lfd, SOMAXCONN); //循环获取连接 while(1){ clie_addr_len = sizeof(clie_addr); //阻塞获取连接 cfd = accept(lfd, (struct sockaddr*)&clie_addr, &clie_addr_len); //打屏提示连接成功 printf("%s:%d connected successfully!\n", inet_ntop(AF_INET, &clie_addr.sin_addr.s_addr, buf, sizeof(buf)), ntohs(clie_addr.sin_port)); //创建进程 pid = fork(); //子进程 if(0 == pid){ //子进程关闭监听套接字 close(lfd); break; } //父进程关闭连接套接字 close(cfd); } //子进程与客户端进程通信 while(0 == pid){ bzero(buf, sizeof(buf)); //读取客户端发来的消息 n = read(cfd, buf, sizeof(buf)); //客户端关闭的情况下 if(0 == n){ close(cfd); printf("%s:%d disconnect successfully!\n", inet_ntop(AF_INET, &clie_addr.sin_addr.s_addr, buf, sizeof(buf)), ntohs(clie_addr.sin_port)); exit(1); } //转换为大小 for(i = 0; i < n; i++){ buf[i] = toupper(buf[i]); } //回写给客户端 write(cfd, buf, n); } return 0; }
.client
#include <stdio.h> #include <stdlib.h> #include <arpa/inet.h> #include <sys/types.h> #include <sys/socket.h> #include <string.h> #include <unistd.h> /* * socket客户端连接服务器 */ #define SERV_PORT 9096 //服务器port #define SERV_ADDR "10.10.101.102" //服务器ip int main(int argc, char* agrv[]){ int sfd; struct sockaddr_in serv_addr; char buf[BUFSIZ]; int n; //创建网络套接字 //AF_INET: 指定ipv4 //SOCK_STREAM: 指定tcp //0: 函数会根据指定的类型来自动指定协议 sfd = socket(AF_INET, SOCK_STREAM, 0); //初始化 bzero(&serv_addr, sizeof(serv_addr)); //指定族 serv_addr.sin_family = AF_INET; //指定ip地址并转换为网络字节序 inet_pton(AF_INET, SERV_ADDR, &serv_addr.sin_addr.s_addr); //指定端口并转换为网络字节序 serv_addr.sin_port = htons(SERV_PORT); //连接服务器 connect(sfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)); //读取键盘输入 while(fgets(buf, sizeof(buf), stdin) != NULL){ //写服务器发送数据 write(sfd, buf, strlen(buf)); bzero(buf, sizeof(buf)); //读取服务器发来数据 n = read(sfd, buf, sizeof(buf)); //服务器关闭 if(0 == n){ close(sfd); break; } //向屏幕输出 write(STDOUT_FILENO, buf, n); bzero(buf, sizeof(buf)); } }
本文出自 “sea” 博客,请务必保留此出处http://lisea.blog.51cto.com/5491873/1790697
linux网络编程----->高并发--->多进程并发服务器
标签:并发服务器 网络编程 高并发 应用程序 include 网络服务
原文地址:http://lisea.blog.51cto.com/5491873/1790697