使用C语言编写一个简单的UDP通信程序,包括服务器端和客户端代码,服务器端实现多线程通信
时间: 2024-03-20 12:44:42 浏览: 77
一个简单的实现客户端和服务器端聊天的C程序.zip_C# 聊天 _CSHARP 网络_CSharp 网络通信_CSharp 通信
好的,这是一个简单的UDP通信程序,包括服务器端和客户端代码,同时服务器端支持多线程通信。
首先是服务器端代码:
```c
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<errno.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<pthread.h>
#define SERVER_PORT 8888
#define MAX_BUFFER_SIZE 1024
void *thread_recv(void *arg)
{
int sockfd = *(int*)arg;
struct sockaddr_in client_addr;
socklen_t addr_len = sizeof(client_addr);
char buffer[MAX_BUFFER_SIZE];
while(1)
{
int n = recvfrom(sockfd, buffer, MAX_BUFFER_SIZE, 0, (struct sockaddr *)&client_addr, &addr_len);
if(n < 0)
{
perror("recvfrom error");
continue;
}
buffer[n] = '\0';
printf("[Server] receive message from %s:%d: %s\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port), buffer);
}
close(sockfd);
}
int main()
{
// 创建 UDP socket
int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if(sockfd < 0)
{
perror("create socket error");
exit(-1);
}
// 绑定监听地址
struct sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(SERVER_PORT);
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
if(bind(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0)
{
perror("bind error");
exit(-1);
}
// 创建多个线程接收数据
pthread_t thread_id[10];
for(int i=0; i<10; i++)
{
if(pthread_create(&thread_id[i], NULL, thread_recv, (void *)&sockfd) != 0)
{
perror("create thread error");
exit(-1);
}
}
// 等待线程结束
for(int i=0; i<10; i++)
{
pthread_join(thread_id[i], NULL);
}
return 0;
}
```
然后是客户端代码:
```c
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<errno.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#define SERVER_IP "127.0.0.1"
#define SERVER_PORT 8888
#define MAX_BUFFER_SIZE 1024
int main()
{
// 创建 UDP socket
int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if(sockfd < 0)
{
perror("create socket error");
exit(-1);
}
// 设置服务器地址
struct sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(SERVER_PORT);
inet_pton(AF_INET, SERVER_IP, &server_addr.sin_addr);
// 发送数据
char buffer[MAX_BUFFER_SIZE];
int n;
while(1)
{
printf("[Client] please input message: ");
fgets(buffer, MAX_BUFFER_SIZE, stdin);
buffer[strlen(buffer)-1] = '\0';
n = sendto(sockfd, buffer, strlen(buffer), 0, (struct sockaddr *)&server_addr, sizeof(server_addr));
if(n < 0)
{
perror("sendto error");
continue;
}
if(strcmp(buffer, "exit") == 0)
{
break;
}
}
close(sockfd);
return 0;
}
```
其中,服务器端使用了多线程来接收数据,每个线程都执行相同的函数 `thread_recv`,该函数的作用就是接收来自客户端的数据并输出到控制台。在服务器端中,我们创建了10个线程,每个线程都会阻塞在 `recvfrom` 函数上来等待数据的到来。当有数据到来时,线程将会被唤醒并处理接收到的数据。
客户端则是通过输入数据来发送给服务器,当输入 `exit` 时,程序将会退出。
注意:由于 UDP 是不可靠的传输协议,因此在发送和接收数据时,需要对 `sendto` 和 `recvfrom` 函数返回值进行判断以确保数据传输的正确性。同时,由于 UDP 是无连接的,因此客户端发送数据时需要自己指定服务器的 IP 和端口号。
阅读全文