socket多线程通信(一个服务器对多个客户端)
程序员文章站
2022-06-06 09:34:48
...
socket多线程通信(一个服务器对多个客户端)
1.服务器端
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>
#include <errno.h>
#define PORT 8888
#define MAX_NUM_CLIENT 10
struct pthread_data{
struct sockaddr_in client_addr;
int sock_fd;
};
void *server_handle(void * arg);
int client_fds[MAX_NUM_CLIENT];
int main()
{
int sock_fd;
struct sockaddr_in serv_addr;
int client_fd;
struct sockaddr_in client_add;
char buff[1024];
socklen_t len;
int num=0;
int i;
for(i=0;i<MAX_NUM_CLIENT;i++)
{
client_fds[i]=0;
}
//创建socket连接
sock_fd=socket(AF_INET,SOCK_STREAM,0);
if(sock_fd==-1)
{
perror("create socket error!");
return 0;
}
else
{
printf("Success to create socket %d\n",sock_fd);
}
//设置server地址结构
bzero(&serv_addr,sizeof(serv_addr)); //初始化结构占用内存
serv_addr.sin_family=AF_INET; //设置传输层类型IPv4
serv_addr.sin_port=htons(PORT); //设置端口号
serv_addr.sin_addr.s_addr=htons(INADDR_ANY); //设置服务器IP地址
bzero(&(serv_addr.sin_zero),8);
//绑定端口
if(bind(sock_fd,(struct sockaddr*)&serv_addr,sizeof(serv_addr))!=0)
{
printf("bind address fail %d\n",errno);
close(sock_fd);
return 0;
}
else
{
printf("Success to bind address!\n");
}
//监听端口
if(listen(sock_fd,MAX_NUM_CLIENT!=0))
{
perror("listen socket error!\n");
close(sock_fd);
return 0;
}
else
{
printf("Success to listen\n");
}
//创建连接客户端的对应套接字
len=sizeof(client_add);
printf("listening...\n");
while(1)
{
//接收客户端连接
client_fd=accept(sock_fd,(struct sockaddr*)&client_add,&len);
if(client_fd<=0)
{
perror("accept error!");
continue;
}
else
{
//遍历所有已连接的客户端
for(i=0;i<MAX_NUM_CLIENT;i++)
{
if(client_fds[i]==0)
{
client_fds[i]=client_fd;
pthread_t tid;
//创建多线程
if(pthread_create(&tid,NULL,server_handle,&client_fd))
{
perror("Fail to create thread");
break;
}
printf("client_fds[%d] join in!\n",i);
num++;
if(num==MAX_NUM_CLIENT-1)
{
printf("client full!\n");
}
break;
}
}
}
}
close(client_fd);
close(sock_fd);
return 0;
}
//每个线程对应一个客户端
void *server_handle(void *arg)
{
int *fd = arg;
int client_fd;
client_fd=*fd;
int i,n,num;
char recvbuf[1024];
char sendbuf[1024];
//找到自己的客户端序号
for(i=0;i<MAX_NUM_CLIENT;i++)
{
if(client_fds[i]==client_fd)
{
num=i;
}
}
//不断接收客户端信息
while((n=recv(client_fd, recvbuf, sizeof(recvbuf), 0))>0)
{
printf("client_fds[%d]:%s\n",num,recvbuf);
//如果客户端发出quit命令,则断开连接,结束线程
if(strcmp(recvbuf,"quit") == 0)
{
for(i=0;i<MAX_NUM_CLIENT;i++)
{
if(client_fds[i]==client_fd)
{
send(client_fds[i], sendbuf, sizeof(sendbuf), 0);
client_fds[i]=0;
printf("client_fds[%d] has been left!\n",i);
sprintf(sendbuf, "client_fds[%d] has been left!\n", i);
}
}
for(i=0;i<MAX_NUM_CLIENT;i++)
{
if(client_fds[i]!=0)
send(client_fds[i], sendbuf, sizeof(sendbuf), 0);
}
break;
}
//向所有客户端发送此客户端发的信息
sprintf(sendbuf,"client_fds[%d]:%s\n",num,recvbuf);
for(i=0;i<MAX_NUM_CLIENT;i++)
{
if(client_fds[i]!=0)
send(client_fds[i], sendbuf, sizeof(sendbuf), 0);
}
memset(recvbuf,0,sizeof(recvbuf));
}
close(client_fd);
pthread_exit(0);
}
2.客户端
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <pthread.h>
#define EHCO_PORT 8888
int sock_fd;
void *client_handle(void *arg)
{
//发送并接收缓冲的数据
char buff[1024];
while(1)
{
gets(buff);
send(sock_fd,buff,1024,0);
}
}
int main()
{
struct sockaddr_in serv_addr;
char recv_buff[1024];
int n,i;
pthread_t thread;
//创建socket
sock_fd=socket(AF_INET,SOCK_STREAM,0);
if(sock_fd==-1)
{
perror("create socket error!");
return 0;
}
else
{
printf("Success to create socket %d\n",sock_fd);
}
//设置server地址结构
bzero(&serv_addr,sizeof(serv_addr)); //初始化结构占用内存
serv_addr.sin_family=AF_INET; //设置传输层类型IPv4
serv_addr.sin_port=htons(EHCO_PORT); //设置端口号
serv_addr.sin_addr.s_addr=inet_addr("127.0.0.1"); //设置服务器IP地址
bzero(&(serv_addr.sin_zero),8);
//连接服务端
if(-1==connect(sock_fd,(struct sockaddr*)&serv_addr,sizeof(serv_addr)))
{
perror("connect fail!");
close(sock_fd);
return 0;
}
printf("Success connect to server!\n");
pthread_create(&thread, NULL, client_handle, NULL);
//发送并接收缓冲的数据
while((n=recv(sock_fd,recv_buff,1024,0))>0)
{
printf("%s",recv_buff);
if(0==strncmp(recv_buff,"quit",4))
{
pthread_cancel(&thread);
break;
}
memset(recv_buff,0,sizeof(recv_buff));
}
close(sock_fd);
return 0;
}
有了这个可以在阿里云服务器搭个服务端,这样就可以用不同的客户端通过服务器通信。
推荐阅读
-
C#使用Socket实现服务器与多个客户端通信(简单的聊天系统)
-
C++ Socket 一个服务器 多个客户端 (阻塞式)
-
C#使用Socket实现服务器与多个客户端通信(简单的聊天系统)
-
linux进程间通信---本地socket套接字(五)---多路IO转接服务器实现一个server对应多个client---poll实现
-
java_多线程_socket通信_多个客户端发送,服务器响应
-
socket多线程通信(一个服务器对多个客户端)
-
Java Socket 使用多线程实现服务器与多个客户端通信
-
C++ Socket 一个服务器 多个客户端 (阻塞式)
-
【java的socket编程】用socket进行多线程客户端-服务器通信
-
linux下用多线程实现socket服务器和客户端的异步通信