C语言基于udp协议使用select实现多线程的服务器端代码
时间: 2024-05-14 08:13:03 浏览: 22
以下是一个基于UDP协议使用select实现多线程的服务器端代码的示例:
```c
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#include<sys/select.h>
#include<pthread.h>
#define BUF_SIZE 1024
#define PORT 12345
void * handle_client(void * arg);
int main()
{
int serv_sock, clnt_sock;
struct sockaddr_in serv_addr, clnt_addr;
socklen_t clnt_addr_size;
char buf[BUF_SIZE];
fd_set reads, temps;
int fd_max, fd_num, str_len;
pthread_t t_id;
serv_sock = socket(AF_INET, SOCK_DGRAM, 0);
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(PORT);
if(bind(serv_sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) == -1)
{
perror("bind() error");
exit(1);
}
FD_ZERO(&reads);
FD_SET(serv_sock, &reads);
fd_max = serv_sock;
while(1)
{
temps = reads;
fd_num = select(fd_max+1, &temps, 0, 0, 0);
if(fd_num == -1)
break;
for(int i=0; i<fd_max+1; i++)
{
if(FD_ISSET(i, &temps))
{
if(i == serv_sock)
{
clnt_addr_size = sizeof(clnt_addr);
str_len = recvfrom(serv_sock, buf, BUF_SIZE, 0, (struct sockaddr *)&clnt_addr, &clnt_addr_size);
clnt_sock = i;
FD_SET(clnt_sock, &reads);
if(fd_max < clnt_sock)
fd_max = clnt_sock;
pthread_create(&t_id, NULL, handle_client, (void *)&clnt_sock);
pthread_detach(t_id);
}
}
}
}
close(serv_sock);
return 0;
}
void * handle_client(void * arg)
{
int clnt_sock = *((int *)arg);
char buf[BUF_SIZE];
int str_len;
while(1)
{
str_len = recv(clnt_sock, buf, BUF_SIZE, 0);
if(str_len == 0)
{
FD_CLR(clnt_sock, &reads);
break;
}
else
{
send(clnt_sock, buf, str_len, 0);
}
}
close(clnt_sock);
return NULL;
}
```