服务器端编程实例(三 多进程并发)
2006-12-02 13:27
344 查看
程序说明: 多进程并发,在接收到请求时,fork个进程,对父进程则关闭连接Socket,而子进程则关闭监听socket,每一个新的accept请求都由子进程来执行,而由父进程继续listen.
/***************************************************************************
* author: denny wqf363@hotmail.com 2006
* desc: 多进程并发
* 座友铭:凡是程序当前不需要的,都是垃圾,80%的时间做20%的事情。(程序的效率)
* *
***************************************************************************/
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <pthread.h>
#include <malloc.h>
#include <stdlib.h>
#define BACKLOG 5
#define MAXDATASIZE 1000
#define PORT 1234
void process_cli(int,sockaddr_in);
int main(int argc,char *argv[]) //需要一个参数 端口号
{
int listenfd, //监听套接字sock
connectfd; //accept 收到的 新套接字
struct sockaddr_in servAddr, //服务器地址
cliAddr; //客户端地址
socklen_t adrlen; //sockaddr地址长度
int servPort; //服务器监听端口号
pid_t pid;
//获得服务器监听的端口号
if(argc!=2)
{
printf("Usage:%s portnumber/a/n",argv[0]);
return 1;
}
if((servPort=atoi(argv[1]))<0)
{
printf("Usage:%s portnumber/a/n",argv[0]);
return 1;
}
/* 服务器端开始建立socket描述符 */
if((listenfd=socket(AF_INET,SOCK_STREAM,0))==-1)
{
fprintf(stderr,"Socket error:%s/n/a",strerror(errno));
return 1;
}
/*设置套接字地址结构体servAddr中的参数,绑定服务器端口号*/
servAddr.sin_family=AF_INET;
servAddr.sin_addr.s_addr=htonl(INADDR_ANY);
servAddr.sin_port=htons(servPort);
if(bind(listenfd,(struct sockaddr *)&servAddr,sizeof(servAddr))<0)
{
printf("Bind error:%s/n/a",strerror(errno));
exit(2);
}
/* 监听sockfd描述符 */
if(listen(listenfd,BACKLOG)==-1)
{
printf("Listen error:%s/n/a",strerror(errno));
exit(3);
}
while(1)
{
printf("%s:waiting for data on port TCP %u/n",argv[0],servPort);
adrlen=sizeof(struct sockaddr_in);
connectfd=accept(listenfd,(struct sockaddr *)&cliAddr,&adrlen);
if(connectfd<0)
{
perror("accetp() error/n");
exit(4);
}
//采用多进程
if((pid=fork()) >0)
{
close(connectfd);
continue;
}
else if(pid==0)
{
close(listenfd);
process_cli(connectfd,cliAddr);
exit(0);
}
else
{
printf("fork() error./n");
exit(0);
}
}
close(listenfd);
}
void process_cli(int connectfd, sockaddr_in client)
{
//....
close(connectfd);
}
/***************************************************************************
* author: denny wqf363@hotmail.com 2006
* desc: 多进程并发
* 座友铭:凡是程序当前不需要的,都是垃圾,80%的时间做20%的事情。(程序的效率)
* *
***************************************************************************/
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <pthread.h>
#include <malloc.h>
#include <stdlib.h>
#define BACKLOG 5
#define MAXDATASIZE 1000
#define PORT 1234
void process_cli(int,sockaddr_in);
int main(int argc,char *argv[]) //需要一个参数 端口号
{
int listenfd, //监听套接字sock
connectfd; //accept 收到的 新套接字
struct sockaddr_in servAddr, //服务器地址
cliAddr; //客户端地址
socklen_t adrlen; //sockaddr地址长度
int servPort; //服务器监听端口号
pid_t pid;
//获得服务器监听的端口号
if(argc!=2)
{
printf("Usage:%s portnumber/a/n",argv[0]);
return 1;
}
if((servPort=atoi(argv[1]))<0)
{
printf("Usage:%s portnumber/a/n",argv[0]);
return 1;
}
/* 服务器端开始建立socket描述符 */
if((listenfd=socket(AF_INET,SOCK_STREAM,0))==-1)
{
fprintf(stderr,"Socket error:%s/n/a",strerror(errno));
return 1;
}
/*设置套接字地址结构体servAddr中的参数,绑定服务器端口号*/
servAddr.sin_family=AF_INET;
servAddr.sin_addr.s_addr=htonl(INADDR_ANY);
servAddr.sin_port=htons(servPort);
if(bind(listenfd,(struct sockaddr *)&servAddr,sizeof(servAddr))<0)
{
printf("Bind error:%s/n/a",strerror(errno));
exit(2);
}
/* 监听sockfd描述符 */
if(listen(listenfd,BACKLOG)==-1)
{
printf("Listen error:%s/n/a",strerror(errno));
exit(3);
}
while(1)
{
printf("%s:waiting for data on port TCP %u/n",argv[0],servPort);
adrlen=sizeof(struct sockaddr_in);
connectfd=accept(listenfd,(struct sockaddr *)&cliAddr,&adrlen);
if(connectfd<0)
{
perror("accetp() error/n");
exit(4);
}
//采用多进程
if((pid=fork()) >0)
{
close(connectfd);
continue;
}
else if(pid==0)
{
close(listenfd);
process_cli(connectfd,cliAddr);
exit(0);
}
else
{
printf("fork() error./n");
exit(0);
}
}
close(listenfd);
}
void process_cli(int connectfd, sockaddr_in client)
{
//....
close(connectfd);
}
相关文章推荐
- 服务器端编程实例(二 单进程并发_IO多路复用)
- Python多进程并发与多线程并发编程实例总结
- 服务器端编程实例(四 多线程并发)
- 网络通讯中服务器端编程实例(一 单进程循环)
- Python并发编程之进程
- Python并发编程之进程
- java并发编程之Thread和Runnable之实例应用(三)
- linux网络编程多进程并发服务器
- (转)iOS并发编程笔记,包含GCD,Operation Queues,Run Loops,如何在后台绘制UI,后台I/O处理,最佳安全实践避免互斥锁死锁优先级反转等,以及如何使用GCD监视进程文件文件夹,并发测试的方案等
- Socket编程实践(4) --多进程并发server
- Java并发编程:线程和进程的创建(转)
- PHP多进程编程实例
- 并发编程之一:多进程
- python之高性能网络编程并发框架eventlet实例
- Java并发编程:CountDownLatch与CyclicBarrier和Semaphore的实例详解
- Android编程实例-获取当前进程名字
- Java并发编程:进程和线程之由来
- 嵌入式成长轨迹25 【Linux应用编程强化】【Linux下的C编程 下】【实例:客户端/服务器端程序】
- PHP多进程编程实例
- Linux下多进程编程之exec函数语法及使用实例