1.我们用多进程来实现多用户的通信
多进程版本——让子进程的子进程即孙子进程,(子进程如果不等父进程会成为僵尸进程)
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<sys/wait.h>
void CreatWorker(int client_fd,struct sockaddr_in* client)
{
pid_t id=fork();
if(id<0)
{
perror("fork");
return;
}
else if(id==0)//子进程
{
if(fork()==0)//孙子进程
{
char buf[1024]={0};
while(1)
{
ssize_t s=read(client_fd,buf,sizeof(buf));
if(s<0)
{
perror("read");
continue;
}
if(s==0)
{
printf("client close\n");
close(client_fd);
break;
}
buf[s]='\0';
printf("client %s say :%s\n",inet_ntoa(client->sin_addr),buf);
write(client_fd,buf,strlen(buf));
}
}
exit(0);
}
else
{
close(client_fd);
waitpid(id,NULL,0);
}
}
int main(int argc,char* argv[])
{
if(argc!=3)
{
printf("./server [ip] [port]\n");
return 1;
}
struct sockaddr_in addr;
addr.sin_family=AF_INET;
addr.sin_addr.s_addr=inet_addr(argv[1]);
addr.sin_port=htons(atoi(argv[2]));
int sock=socket(AF_INET,SOCK_STREAM,0);
if(sock<0)
{
perror("socket");
return 2;
}
int ret=bind(sock,(struct sockaddr*)&addr,sizeof(addr));
if(ret<0)
{
perror("bind");
return 3;
}
ret=listen(sock,10);
if(ret<0)
{
perror("listen");
return 4;
}
while(1)
{
struct sockaddr_in client;
socklen_t len=sizeof(client);
int client_fd=accept(sock,(struct sockaddr*)&client,&len);
if(client_fd<0)
{
perror("accept");
continue;
}
CreatWorker(client_fd,&client);
}
return 0;
}
2.多线程版本——新线程则执行请求,主线程返会去继续执行
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<pthread.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<sys/wait.h>
void Request(void* arg)
{
int client_fd=(int)arg;
char buf[1024]={0};
while(1)
{
ssize_t s=read(client_fd,buf,sizeof(buf));
if(s<0)
{
perror("read");
continue;
}
else if(s==0)
{
printf("client close\n");
close(client_fd);
break;
}
buf[s]=0;
printf("client say %s\n",buf);
write(client_fd,buf,strlen(buf));
}
close(client_fd);
return (void*)0;
}
int main(int argc,char* argv[])
{
if(argc!=3)
{
printf("./server [ip][port]\n");
return 1;
}
struct sockaddr_in addr;
addr.sin_family=AF_INET;
addr.sin_port=htons(atoi(argv[2]));
addr.sin_addr.s_addr=inet_addr(argv[1]);
int sock=socket(AF_INET,SOCK_STREAM,0);
if(sock<0)
{
perror("sock");
return 1;
}
int ret=bind(sock,(struct sockaddr*)&addr,sizeof(addr));
if(ret<0)
{
perror("bind");
return 1;
}
ret=listen(sock,10);
if(ret<0)
{
perror("listen");
return 1;
}
while(1)
{
struct sockaddr_in client;
socklen_t len=sizeof(client);
int client_fd=accept(sock,(struct sockaddr*)&client,&len);
if(client_fd<0)
{
perror("accept");
continue;
}
pthread_t tid;
pthread_create(&tid,NULL,Request,(void*)client_fd);
pthread_detach(tid);
}
return 0;
}