Linux高性能服务器编程就是在Linux网络编程的基础上,将服务器与客户端建立面向连接时,只能一台服务器与一台客户机通信,改变为一台服务器可以与多台客户端通信。
这里,我们怎样能做到一台服务器与多台客户机通信呢?我们可以通过多进程通信和多线程通信来完成这个功能。
多进程通信是通过fork()函数,由父进程通过fork,生成子进程,实现多进程,使一台服务器可以与多台客户端进行通信。
多进程流程一般为:前面跟单台服务器与单台客户机进行通信的过程基本一致,不同点在于:在while(1)循环中服务器的accept后进行fork操作,生成子进程,这样一个服务器就可以同时处理多个客户机的要求。
多线程通信与多进程通信的过程基本上都是一致的,就是将进程创建子进程的过程,改变为创建多个线程的过程,这里我先展现一下多线程编程。
服务器的程序:
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<fcntl.h>
#include<string.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#include<assert.h>
#include<pthread.h>
void *fun(void *arg)
{
while(1)
{
int c=(int)arg;
char buff[128]={0};
int n=recv(c,buff,127,0);
if(n<=0)
{
close(c);
continue;
}
if(strcmp(buff,"end")==0)
{
printf("This time end.\n");
break;
}
printf("%d: %s\n",c,buff);
send(c,"OK",2,0);
}
}
int main()
{
int sockfd=socket(PF_INET,SOCK_STREAM,0);
assert(sockfd != -1);
struct sockaddr_in ser,cli;
ser.sin_family=AF_INET;
ser.sin_port=htons(7000);
ser.sin_addr.s_addr=inet_addr("127.0.0.1");
bind(sockfd,(struct sockaddr*)(&ser),sizeof(ser));
listen(sockfd,5);
while(1)
{
int client=sizeof(cli);
int c=accept(sockfd,(struct sockaddr*)(&cli),&client);
if(c<=0)
{
printf("error\n");
}
pthread_t id;
int ret=pthread_create(&id,NULL,fun,(void *)c);
assert(ret==0);
}
close(sockfd);
}
客户机的程序:
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<fcntl.h>
#include<string.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#include<assert.h>
int main()
{
int sockfd=socket(PF_INET,SOCK_STREAM,0);
assert(sockfd != -1);
struct sockaddr_in ser,cli;
ser.sin_family=AF_INET;
ser.sin_port=htons(7000);
ser.sin_addr.s_addr=inet_addr("127.0.0.1");
connect(sockfd,(struct sockaddr*)(&ser),sizeof(ser));
while(1)
{
printf("please input: ");
fflush(stdout);
char buff[128]={0};
fgets(buff,128,stdin);
buff[strlen(buff)-1] = '\0';
send(sockfd,buff,127,0);
if(strcmp(buff,"end")==0)
{
break;
}
char recvbuff[128]={0};
recv(sockfd,recvbuff,127,0);
printf("%s\n",recvbuff);
}
close(sockfd);
}
运行结果:
可见,我们实现了一个服务器同时与多个客户机进行通信。