接上一篇,pgpool-II中是如何实现进程池的,自己实现线程池。可以正常运行。
server端代码:con-server03.c
复制代码
#include<netinet/in.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<sys/signal.h>
#include<sys/wait.h>
#include<sys/time.h>
#define HELLO_WORLD_SERVER_PORT 6666
#define LENGTH_OF_LISTEN_QUEUE 20
#define BUFFER_SIZE 1024
int main(int argc, char **argv){
struct sockaddr_in server_addr;
bzero(&server_addr,sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = htons(INADDR_ANY);
server_addr.sin_port = htons(HELLO_WORLD_SERVER_PORT);
int server_socket = socket(AF_INET,SOCK_STREAM,0);
if( server_socket < 0){
printf("Create Socket Failed!");
exit(1);
}
if( bind(server_socket,(struct sockaddr*)&server_addr,sizeof(server_addr))){
printf("Server Bind Port : %d Failed!", HELLO_WORLD_SERVER_PORT);
exit(1);
}
if ( listen(server_socket, LENGTH_OF_LISTEN_QUEUE) ){
printf("Server Listen Failed!");
exit(1);
}
//prepare for forking children
struct sockaddr_in client_addr;
socklen_t length = sizeof(client_addr);
int procnt;
int fds;
fd_set readmask;
int newsock;
int fd = 0;
for (procnt=0; procnt<10; procnt++){
int child_process_pid = fork();
if(child_process_pid == 0 ){
fprintf(stderr,"Child %d is born.\n",getpid());
while(1){
FD_ZERO(&readmask);
FD_SET(server_socket, &readmask);
struct timeval timeout;
timeout.tv_sec=30;
timeout.tv_usec=0;
int ssocket=server_socket+1;
fds = select( ssocket, &readmask, NULL, NULL,&timeout);
/* timeout */
if (fds == 0){
sleep(5);
continue;
}
if (FD_ISSET(server_socket, &readmask)){
fd =server_socket;
}
memset( &client_addr, 0, sizeof(client_addr));
newsock = accept(fd, (struct sockaddr *)&client_addr, &length);
char buffer[BUFFER_SIZE];
bzero(buffer, BUFFER_SIZE);
strcpy(buffer,"Hello,World! FromServer! ");
int pd;
pd=getpid();
char cpd[10];
sprintf(cpd,"%d",pd);
strcat(buffer,cpd);
strcat(buffer,"\n");
send(newsock,buffer,BUFFER_SIZE,0);
bzero(buffer,BUFFER_SIZE);
length = recv(newsock,buffer,BUFFER_SIZE,0);
if (length < 0){
printf("Server Recieve Data Failed!\n");
exit(1);
}
fprintf(stderr,"got: %s in %d\n",buffer,getpid());
close(newsock);
}///while circle ends
exit(0);///child ends.never goes here
}else{
//parent process, do nothing
}
} /// for circle of forking ends
for(;;){
sleep(10);
fprintf(stderr,"I am main process waked from sleep.\n");
}
close(server_socket);
return 0;
}
复制代码
client端代码:con-client.c
复制代码
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define HELLO_WORLD_SERVER_PORT 6666
#define BUFFER_SIZE 1024
void talk_to_server(char ** argv){
struct sockaddr_in client_addr;
bzero(&client_addr,sizeof(client_addr));
client_addr.sin_family = AF_INET;
client_addr.sin_addr.s_addr = htons(INADDR_ANY);
client_addr.sin_port = htons(0);
int client_socket = socket(AF_INET,SOCK_STREAM,0);
if( client_socket < 0){
printf("Create Socket Failed!\n");
exit(1);
}
if( bind(client_socket,(struct sockaddr*)&client_addr,sizeof(client_addr))){
printf("Client Bind Port Failed!\n");
exit(1);
}
struct sockaddr_in server_addr;
bzero(&server_addr,sizeof(server_addr));
server_addr.sin_family = AF_INET;
if(inet_aton(argv[1],&server_addr.sin_addr) == 0){
printf("Server IP Address Error!\n");
exit(1);
}
server_addr.sin_port = htons(HELLO_WORLD_SERVER_PORT);
socklen_t server_addr_length = sizeof(server_addr);
if( connect( client_socket, (struct sockaddr*)&server_addr,
server_addr_length) < 0){
printf("Can Not Connect To %s!\n",argv[1]);
exit(1);
}
char buffer[BUFFER_SIZE];
bzero(buffer,BUFFER_SIZE);
int length = recv( client_socket, buffer,BUFFER_SIZE,0);
if(length < 0){
printf("Recieve Data From Server %s Failed!\n", argv[1]);
exit(1);
}
printf("From Server %s :\t%s",argv[1],buffer);
bzero(buffer,BUFFER_SIZE);
char name[64];
gethostname(name,sizeof(name));
strcpy(buffer,name);
send(client_socket,buffer,BUFFER_SIZE,0);
close(client_socket);
}
int main(int argc, char **argv){
if (argc != 2){
printf("Usage: ./%s ServerIPAddress\n",argv[0]);
exit(1);
}
int i=0;
for(i=0; i<10000; i++){
talk_to_server(argv);
sleep(10);
}
return 0;
}
复制代码
基本上来说,server端的实现方式,就是:
监听某个port, listen后,开始建立若干的子进程。在父进程里进入sleep/循环;
在子进程里面,select/accept ,accept后作动作,然后循环往复。
好像酒店大堂的门口,开了门纳客(监听);
然后派一批员工(子进程)等在门口(listen/accept),
若有客人来(网络请求),哪个员工(子进程)逮住了就给迎进酒店,领位(服务),然后循环往复。
本文转自健哥的数据花园博客园博客,原文链接:http://www.cnblogs.com/gaojian/archive/2012/08/06/2624979.html,如需转载请自行联系原作者