一.前言
要实现tcp通信服务器处理并法的任务,使用多线程或者多线程来解决
这里我们使用多进程来实现:
1.一个父进程,多个子进程
2.父进程负责等待并接受客户端的连接
3.子进程:完成通信,接收一个客户端的连接,就创建一个子进程来通信
二.代码实例实现
服务端
#include <stdio.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <signal.h>
#include <wait.h>
#include <errno.h>
void recyleChild(int arg)
{
while(1)
{
int ret = waitpid(-1,NULL,WNOHANG);
if(ret == -1)
{
//所有的子进程回收完毕
break;
}
else if(ret == 0)
{
//还有子进程活着
break;
}
else if(ret > 0)
{
//被回收了
printf("子进程%d,被回收了\n",ret);
}
}
}
int main()
{
//注册信号捕捉
struct sigaction act;
act.sa_flags = 0;
sigemptyset(&act.sa_mask);
act.sa_handler = recyleChild;
sigaction(SIGCHLD,&act,0);
int sockfd = socket(AF_INET,SOCK_STREAM,0);
if(sockfd == -1)
{
perror("socket");
exit(-1);
}
struct sockaddr_in server;
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons(8000);
if(bind(sockfd,(struct sockaddr*)&server,sizeof(server))==-1)
{
perror("bind");
exit(-1);
}
if(listen(sockfd, 8) == -1)
{
perror("listen");
exit(-1);
}
int client_fd;
struct sockaddr_in client_addr;
int len = sizeof(client_addr);
while(1)
{
client_fd = accept(sockfd,(struct sockaddr*)&client_addr,&len);
if(client_fd == -1)
{
if(errno == EINTR)
{
//产生了中断
continue;
}
perror("accept");
exit(-1);
}
//每一个连接进来就创建一个子进程来根客户端通信
pid_t pid = fork();
if(pid == -1)
{
perror("fork");
}
else if(pid == 0)
{
//子进程
char client_ip[16];
inet_ntop(AF_INET,(const void *)&client_addr.sin_addr.s_addr,client_ip,sizeof(client_ip));
unsigned short client_port = ntohs(client_addr.sin_port);
printf("客户端ip is : %s, port is : %d\n",client_ip,client_port);
//接收客户端发来的信息
char recvBuf[1024];
while(1)
{
memset(recvBuf,0,sizeof(recvBuf));
int data_len = read(client_fd,recvBuf,sizeof(recvBuf));
if(data_len == -1)
{
perror("read");
break;
}
else if(data_len > 0)
{
printf("recv client data:%s\n",recvBuf);
write(client_fd,recvBuf,strlen(recvBuf));
}
else if(data_len == 0)
{
printf("客户端断开连接\n");
break;
}
}
close(client_fd);
exit(0); //退出当前子进程
}
}
close(sockfd);
return 0;
}
客户端
#include <stdio.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{
int sockfd = socket(AF_INET,SOCK_STREAM,0);
if(sockfd == -1)
{
perror("socket");
exit(-1);
}
struct sockaddr_in client;
client.sin_family = AF_INET;
client.sin_addr.s_addr = inet_addr("127.0.0.1");
client.sin_port = htons(8000);
if(connect(sockfd,(const struct sockaddr*)&client,sizeof(client)) == -1)
{
perror("connect");
exit(-1);
}
//写
char *client_send_data;
char client_recv_buf[1024];
int len;
while(1)
{
printf("亲爱的用户,请发送你要发送给服务器的数据:");
scanf("%s",client_send_data);
len = write(sockfd,client_send_data,strlen(client_send_data));
if(len == -1)
{
perror("write");
break;
}
memset(client_recv_buf,0,sizeof(client_recv_buf));
len = read(sockfd,client_recv_buf,sizeof(client_recv_buf));
if(len == -1)
{
perror("read");
break;
}
else if(len > 0)
{
printf("接收到服务器端的回射数据:%s\n",client_recv_buf);
}
else if(len == 0)
{
printf("服务器断开连接\n");
break;
}
sleep(1);
}
close(sockfd);
return 0;
}