TCP多进程并发服务器的思想是每一个客户端的请求并不直接由服务器直接处理,而是由服务器创建一个子进程来处理
基本流程:
while(1){
int connfd=accept();
if(fork()==0){
close(sockfd);
fun();
close(connfd);
exit(0);
}
close(connfd);
}
服务端代码:tcpForkServer.cpp
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<string>
#include<cstring>
#include<unistd.h>
#include<errno.h>
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
using namespace std;
int main(int argc,char * argv[]){
//创建套接字
int sockFd=socket(AF_INET,SOCK_STREAM,0);
if(sockFd<0)
{
puts("Create socket failed!");
return -1;
}
//设置地址信息
sockaddr_in saddr,raddr;
int size=sizeof(saddr);
saddr.sin_family=AF_INET;
saddr.sin_addr.s_addr=inet_addr(argv[1]);
saddr.sin_port=htons(atoi(argv[2]));
//设置端口复用
char on=1;
setsockopt(sockFd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on));
//绑定
int ret=bind(sockFd,(sockaddr*)&saddr,size);
if(ret==-1){
puts("Bind failed!");
return -1;
}
//监听
ret=listen(sockFd,5);
if(ret<0){
puts("Listen failed");
return -1;
}
//主进程循环等待客户端连接
while(1){
char cli_ip[INET_ADDRSTRLEN]={0};
puts("Father process is waiting client....");
int newFd=accept(sockFd,(sockaddr*)&raddr,(socklen_t*)&size);
if(newFd<0){
puts("Accept failed");
}
pid_t pid=fork();
if(pid<0){
perror("fork");
_exit(0);
}
else if(pid==0){
close(sockFd);
char rbuf[1024]={0};
int recv_len=0;
//打印客户端的IP地址和端口号
memset(cli_ip,0,sizeof(cli_ip));
inet_ntop(AF_INET,&raddr.sin_addr,cli_ip,INET_ADDRSTRLEN);
printf("-----------------\n");
printf("client ip=%s ,port=%d \n",cli_ip,ntohs(raddr.sin_port));
//循环接收信息
while(1){
recv_len=recv(newFd,rbuf,sizeof(rbuf),0);
if(recv_len<0)
break;
printf("Recv buf(%s)\n",rbuf);
send(newFd,rbuf,recv_len,0);
}
printf("client_port %d closed! \n",ntohs(raddr.sin_port));
close(newFd);
exit(0);
}
else if(pid>0)
close(newFd);
}
close(sockFd);
return 0;
}
客户端代码:tcpClient.cpp
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<string.h>
#include<unistd.h>
#include<errno.h>
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
using namespace std;
int main(int argc,char *argv[]){
int sockFd=socket(AF_INET,SOCK_STREAM,0);
if(sockFd<0){
puts("Create socket failed!");
return -1;
}
sockaddr_in saddr;
int size=sizeof(sockaddr_in);
saddr.sin_family=AF_INET;
saddr.sin_addr.s_addr=inet_addr(argv[1]);
saddr.sin_port=htons(atoi(argv[2]));
char on=1;
setsockopt(sockFd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on));
int ret=connect(sockFd,(sockaddr*)&saddr,size);
if(ret<0){
puts("Connect Failed!");
return -1;
}
int val=sizeof(sockaddr);
char rbuf[50],sbuf[100];
while(1){
puts("Please enter data:");
scanf("%s",sbuf,sizeof(sbuf));
ret=sendto(sockFd,sbuf,strlen(sbuf),0,
(sockaddr*)&saddr,val);
if(ret<0){
perror("send failed!");
}
ret=recv(sockFd,rbuf,sizeof(rbuf),0);
if(ret<0){
perror("recv failed");
}
printf("server reply: %s\n",rbuf);
memset(rbuf,0,sizeof(rbuf));
memset(sbuf,0,sizeof(sbuf));
}
close(sockFd);
return 0;
}
运行结果:服务端可以看见客户端的IP地址相同但端口号不同说明是三条连接