Linux系统编程74 网络编程8 - 流式套接字_静态进程池版

注意:

accept()本身就可以实现单一的连接,也就是说他本身就可以实现互斥。当有N个进程阻塞在accept()位置的时候,只有一个进程能正常连接,其他进程依然阻塞。

此处静态进程池的缺点:
此处进程池中有4个进程在同时准备接收C端数据请求,也就是说该S端程序,最多也只能够同时对接4个C端,而如果一下来了一万个C端请求,那么此时也只能一次性处理四个C端,下一次再处理四个,也就是四个 四个的处理,显然是不够的。所以如果需要 继续优化,可以使用动态内存池,即 保证线程池中至少有n1个进程在空闲等待接收请求,最大有n2个进程同时工作,这样就比较有弹性。

server.c

#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>
#include "proto.h"

#define IPSTRSIZE 40
#define BUFSIZE 1024
#define PROCNUM 4

static void server_loop(int sd);

static void server_job(int sd)
{
	char buf[BUFSIZE];
	int len;
	
	len = sprintf(buf,FMT_STAMP,(long long)time(NULL));
	
	if(send(sd,buf,len,0) < 0)
	{
		perror("send()");
		exit(1);
	}
}


int main()
{
	int sd;
	pid_t pid;
	struct sockaddr_in laddr;

	sd = socket(AF_INET,SOCK_STREAM,0/*IPPROTO_TCP*/);
	if(sd < 0)
	{
		perror("soccket()");
		exit(1);
	}

	laddr.sin_family = AF_INET;
	laddr.sin_port = htons(atoi(SERVERPORT));
	inet_pton(AF_INET,"0.0.0.0",&laddr.sin_addr);//0.0.0.0:any address

	if(bind(sd,(void *)&laddr,sizeof(laddr)) < 0)
	{
		perror("bind");
		exit(1);
	}


	if(listen(sd,200) < 0)
	{
		perror("listen");
		exit(1);	
	}

	for(int i=0; i<PROCNUM; i++)
	{
		pid = fork();
		if(pid < 0)
		{
			perror("fork()");
			exit(1);
		}
		if(pid == 0)
		{
			server_loop(sd);
			exit(0);
		}

		for(i = 0; i<PROCNUM; i++)
			wait();

		close(sd);
		exit(0);
	}
}
	
static void server_loop(int sd)
{
	struct sockaddr_in raddr;
	socklen_t raddr_len;
	int newsd;
	char ipstr[IPSTRSIZE];

	/* !!!! */
	raddr_len = sizeof(raddr);

	while(1)
	{
		newsd = accept(sd,(void *)&raddr,&raddr_len);
		if(newsd < 0)
		{
			perror("accept");
			exit(1);	
		}

		inet_ntop(AF_INET,&raddr.sin_addr,ipstr,IPSTRSIZE);

		printf("[%d]Client %s:%d\n",getpid(),ipstr,ntohs(raddr.sin_port));

		server_job(newsd);

		close(newsd);

	}	

	close(sd);


}

Guess you like

Origin blog.csdn.net/LinuxArmbiggod/article/details/115499799