Linux网络编程之---多线程实现并发服务器
下面我们来使用tcp集合多线程实现并发服务器
一.服务端
#include <stdio.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
typedef struct sockinfo
{
char ip[16];
unsigned short port;
}sockinfo;
sockinfo s;
void *working(void *arg)
{
//子线程和客户端通信
int fd = *(int *)arg;
printf("%d\n",fd);
char recv_buff[1024];
printf("接收到新的客户端,ip:%s,端口:%d\n",s.ip,s.port);
while(1)
{
int len = read(fd,recv_buff,sizeof(recv_buff));
if(len > 0)
{
printf("接收到新的客户端的数据:%s\n",recv_buff);
len = write(fd,recv_buff,strlen(recv_buff));
}
else if(len == -1)
{
perror("read");
break;
}
else if(len == 0)
{
printf("客户端断开连接\n");
break;;
}
}
close(fd);
return NULL;
}
int main()
{
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,(const struct sockaddr*)&server,sizeof(server)) == -1)
{
perror("bind");
exit(-1);
}
if(listen(sockfd,8) == -1)
{
perror("listen");
exit(-1);
}
//循环等待客户端连接,一旦有客户端连接进来就创建一个子线程连接进来
struct sockaddr_in client;
socklen_t client_addr_len = sizeof(client);
int client_fd;
char client_ip[16];
unsigned short client_port;
while(1)
{
client_fd = accept(sockfd,(struct sockaddr*)&client,&client_addr_len);
if(client_fd == -1)
{
perror("accept");
exit(-1);
}
inet_ntop(AF_INET,(const void *)&client.sin_addr.s_addr,client_ip,sizeof(client_ip));
client_port = ntohs(client.sin_port);
memcpy(s.ip,client_ip,sizeof(client_ip));
s.port = client_port;
//创建线程
pthread_t tid;
pthread_create(&tid,NULL,working,(void *)&client_fd);
pthread_detach(tid);
}
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;
}
三.运行效果
可以发现我们使用tcp结合多线程的服务器可以同时接收多个客户端的连接,并且可以同时收发数据.