网络编程(5)多进程并发服务器
2014-02-15 01:04
351 查看
多进程并发服务器基本流程是,accept接收一个客户端连接,就创建一个子进程来处理它,即一个子进程对应一个客户端。
简单说就是 父进程负责接收请求,子进程负责处理请求。
整理代码如下:
注意在代码中出现父子各close(客户端连接)一次的原因是:
当fork()返回时后,与监听和连接描述符相关的文件表项的访问计数都加1.
所以都要各自关一次,计数才会为0,才是真正的关闭。
代码中用到的头文件在: 网络编程(1)跨平台的Socket同步阻塞工作模式例子
MAIL: xcl_168@aliyun.com
BLOG: http://blog.csdn.net/xcl168
简单说就是 父进程负责接收请求,子进程负责处理请求。
整理代码如下:
/************************************************* Author: xiongchuanliang Description: 多进程并发服务器,服务端代码 编译命令: Linux: g++ -o tcpserver_fork tcpserver_fork.cpp -m64 -I./common **************************************************/ // 服务端代码 #include <stdio.h> #include <stdlib.h> #include <string.h> #include "initsock.h" #include "common.h" CInitSock initSock; int main(int argc, char* argv[]) { int n = 0; //创建套接字 SOCKET sListen = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); if(sListen == INVALID_SOCKET) { PrintError("socket() failed.\n"); exit(EXIT_FAILURE); } //绑定本地IP和端口到套接字 struct sockaddr_in server_addr; server_addr.sin_family = AF_INET; server_addr.sin_port = htons(SERVPORT); //大于1024且小于65535 server_addr.sin_addr.s_addr = INADDR_ANY; bzero(&(server_addr.sin_zero),8); //SO_REUSEADDR : 使bind函数能允许地址立即重用 int on = 1; setsockopt( sListen, SOL_SOCKET, SO_REUSEADDR, (const char*)&on, sizeof(on) ); if(bind(sListen,(struct sockaddr *)&server_addr,sizeof(struct sockaddr)) == SOCKET_ERROR) { PrintError("bind() failed."); exit(EXIT_FAILURE); } //开始监听 if(listen(sListen, BACKLOG) == SOCKET_ERROR) { PrintError("sListen() failed."); exit(EXIT_FAILURE); } struct sockaddr_in remoteAddr; socklen_t nAddrlen = sizeof(struct sockaddr_in); //循环接收数据 while(1){ SOCKET sClient; printf("等待客户端连接中...\n"); sClient = accept(sListen,(struct sockaddr *)&remoteAddr, &nAddrlen); if(sClient == INVALID_SOCKET) { PrintError("accept() failed."); continue; } printf("接收到一个客户端连接:%s \n",inet_ntoa(remoteAddr.sin_addr)); //创建子进程,处理客户端连接 if( (n=fork()) == 0) { char recvData[MAXDATASIZE]={0}; //关闭监听套接字 close(sListen); //接收数据 int recvbytes = recv(sClient, recvData, MAXDATASIZE, 0); if( recvbytes == 0) { printf("recv() no data!\n"); }else if( recvbytes < 0) { PrintError("recv() failed"); }else if(recvbytes > 0) { recvData[recvbytes]='\0'; printf("收到信息:%s\n",recvData); } //发送数据到客户端 char * sendData = "客户端,你好啊!\n"; send(sClient, sendData, strlen(sendData), 0); //关闭子进程连接的套接字 close(sClient); exit(EXIT_SUCCESS); //父进程准备接受下一个客户端的连接 //}else if(n > 0){ }else if(n < 0){ printf("fork() failed! %s\n",strerror(errno)); exit(EXIT_FAILURE); } //关闭套接字 close(sClient); }// end while exit(EXIT_SUCCESS); }
注意在代码中出现父子各close(客户端连接)一次的原因是:
当fork()返回时后,与监听和连接描述符相关的文件表项的访问计数都加1.
所以都要各自关一次,计数才会为0,才是真正的关闭。
代码中用到的头文件在: 网络编程(1)跨平台的Socket同步阻塞工作模式例子
MAIL: xcl_168@aliyun.com
BLOG: http://blog.csdn.net/xcl168
相关文章推荐
- 网络编程之并发服务器(线程,进程)
- linux网络编程----->高并发--->多进程并发服务器
- linux网络编程多进程并发服务器
- 【Unix 网络编程】服务器网络编程模型——多进程并发模型
- 网络编程(6)单进程多线程并发服务器实现
- 网络编程释疑之:单台服务器上的并发TCP连接数可以有多少
- [zz] 多进程并发服务器编程
- linux网络编程----->高并发--->多线程并发服务器
- 网络编程(29)—— socket的close函数以及shutdown函数在多进程服务器中的不同表现(二)
- 网络编程释疑之:单台服务器上的并发TCP连接数可以有多少
- 网络编程三---多线程/进程解决并发问题
- Liunx网络编程---并发服务器
- Linux网络编程:tcp并发服务器(I/O复用之select)
- Linux网络编程之高级并发服务器(转)
- Linux网络编程之高级并发服务器
- Linux网络编程之简单并发服务器
- linux网络编程:并发服务器的模型
- 【Linux网络编程】基于TCP单进程版本阻塞式客户端/服务器
- Windows下的网络编程(tcp循环并发服务器)
- Linux网络编程并发服务器模型