多进程并发TCP服务器示例

多进程并发TCP服务器示例

程序逻辑:
1.TCP服务器先绑定本地地址信息,处于监听状态;
2.设置信号(SIGCHLD)时回收子进程;
2.在循环中等待连接;
3.当收到客户端连接,开启子进程,在子进程处理与客户端的通信操作(关闭掉监听套接字);
4.主进程关闭掉创建子进程创建生成的套接字;

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <signal.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <netinet/ip.h>
void child_process(int confd,struct sockaddr_in cl_addr)
{
	char buf[1024]={0};
	ssize_t read_len;
	while(1)
	{
		memset(buf,0,sizeof(buf));
		read_len=read(confd,buf,sizeof(buf));
		if(read_len<0)
		{
			perror("Fail to read");
			return ;
		}
		else if(read_len==0)
		{
			printf("客户端退出!\n");
			break;
		}
		else
		{
			printf("[%s:%d]:",inet_ntoa(cl_addr.sin_addr),ntohs(cl_addr.sin_port));
			if(strncmp(buf,"quit",4)==0)
			{
				printf("已退出!\n");
				break;
			}	
			printf("%s\n",buf);
			write(confd,buf,strlen(buf));//收到消息再返回去
		}
	}
	exit(EXIT_SUCCESS);
}
void child_wait(int arg)
{
	waitpid(-1,NULL,WNOHANG);//当收到子进程退出,则立即回收他
	return;
}
int main(int argc, const char *argv[])
{
	pid_t pid;
	int ret;
	int sockfd,confd;
	struct sockaddr_in saddr,caddr;
	int client_len=0;
	client_len=sizeof(caddr);
	if(argc!=2)
	{
		fprintf(stderr,"usage:%s 8888",argv[0]);
		return -1;
	}
	sockfd=socket(AF_INET,SOCK_STREAM,0);
	if(sockfd<0)
	{
		perror("Fail to socket");
		return -1;
	}
	printf("socket\n");
	memset(&saddr,0,sizeof(saddr));
	saddr.sin_family=AF_INET;
	saddr.sin_port=htons(atoi(argv[1]));
	saddr.sin_addr.s_addr=htonl(INADDR_ANY);//这里一定要是htonl(),其它函数会发生段错误
	ret=bind(sockfd,(struct sockaddr *)&saddr,sizeof(saddr));
	if(ret<0)
	{
		perror("Fail to bind");
		return -1;
	}

	printf("bind\n");
	
	ret=listen(sockfd,10);
	if(ret<0)
	{
		perror("Fail to listen");
		return -1;
	}
	
	if(signal(SIGCHLD,child_wait)==SIG_ERR)//子进程状态改变时给父进程发送信号回收掉子进程
	{
		perror("Fail to signal");
		return -1;
	}
	
	while(1)
	{
		memset(&caddr,0,sizeof(caddr));
		confd=accept(sockfd,(struct sockaddr *)&caddr,&client_len);
		if(confd<0)
		{
			perror("Fail to accept");
			return -1;
		}
		pid = fork();
		if(pid<0)
		{
			perror("Fail to fork");
			return -1;
		}
		else if(pid==0)
		{
			close(sockfd);//监听套接字
			child_process(confd,caddr);
		}
		else
		{
			close(confd);//创建子进程的套接字
			
		}	
	}
	close(sockfd);
	close(confd);	
	return 0;
}







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jun8086

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值