服务端
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <arpa/inet.h>
5 #include <sys/socket.h>
6 #include <pthread.h>
7 #include <unistd.h>
8 #define SERVER_IP "192.168.124.94"
9 #define SERVER_PORT 9999
10
11 struct client_info {
12 struct sockaddr_in address;
13 int socket;
14 };
15
16 struct client_info clients[10];
17 int num_clients = 0;
18 pthread_mutex_t mutex;
19
20 void *client_handler(void *arg) {
21 char buffer[1024];
22 struct client_info *client = (struct client_info *)arg;
23
24 while (1) {
25 // 接收消息
26 int bytes_received = recvfrom(client->socket, buffer, sizeof(buffer), 0, NULL, NULL);
27 buffer[bytes_received] = '\0';
28
29 if (strcmp(buffer, "EXIT") == 0) {
30 // 客户端退出群聊
31 pthread_mutex_lock(&mutex);
32 for (int i = 0; i < num_clients; i++) {
33 if (clients[i].socket == client->socket) {
34 printf("Client %s:%d has left the chat\n", inet_ntoa(client->address.sin_addr), ntohs(client->address.sin_port));
35 // 移除退出的客户端
36 for (int j = i; j < num_clients - 1; j++) {
37 clients[j] = clients[j + 1];
38 }
39 num_clients--;
40 break;
41 }
42 }
43 // 发送退出消息给所有在线客户端
44 for (int i = 0; i < num_clients; i++) {
45 sendto(clients[i].socket, "Client has left the chat", strlen("Client has left the chat"), 0, (struct sockaddr *)&clients[i].address, sizeof(clients[i].address));
46 }
47 pthread_mutex_unlock(&mutex);
48 close(client->socket);
49 pthread_exit(NULL);
50 }
51
52 // 广播消息给所有客户端
53 pthread_mutex_lock(&mutex);
54 for (int i = 0; i < num_clients; i++) {
55 sendto(clients[i].socket, buffer, strlen(buffer), 0, (struct sockaddr *)&clients[i].address, sizeof(clients[i].address));
56 }
57 pthread_mutex_unlock(&mutex);
58 }
59
60 return NULL;
61 }
62
63 int main() {
64 struct sockaddr_in server_addr;
65 int server_socket;
66
67 // 创建UDP套接字
68 server_socket = socket(AF_INET, SOCK_DGRAM, 0);
69
70 memset(&server_addr, 0, sizeof(server_addr));
71 server_addr.sin_family = AF_INET;
72 server_addr.sin_addr.s_addr = inet_addr(SERVER_IP);
73 server_addr.sin_port = htons(SERVER_PORT);
74
75 // 绑定服务器地址
76 bind(server_socket, (struct sockaddr *)&server_addr, sizeof(server_addr));
77
78 printf("Server started...\n");
79
80 pthread_t tid;
81
82 while (1) {
83 struct client_info new_client;
84 socklen_t client_len = sizeof(new_client.address);
85
86 // 接收加入群聊的消息
87 char join_message[5];
88 recvfrom(server_socket, join_message, sizeof(join_message), 0, (struct sockaddr *)&new_client.address, &client_len);
89
90 // 发送上线信息给所有在线客户端
91 pthread_mutex_lock(&mutex);
92 for (int i = 0; i < num_clients; i++) {
93 sendto(clients[i].socket, "New client joined the chat", strlen("New client joined the chat"), 0, (struct sockaddr *)&clients[i].address, sizeof(clients[i].address));
94 }
95 pthread_mutex_unlock(&mutex);
96
97 // 添加新客户端到客户端列表
98 new_client.socket = server_socket;
99 clients[num_clients++] = new_client;
100
101 // 创建线程处理新客户端消息
102 pthread_create(&tid, NULL, client_handler, (void *)&new_client);
103 }
104
105 close(server_socket);
106
107 return 0;
108 }
109
~
~
客户端:
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <arpa/inet.h>
5 #include <sys/socket.h>
6 #include <unistd.h>
7
8 #define SERVER_IP "192.168.124.94"
9 #define SERVER_PORT 9999
0
1 int main() {
2 struct sockaddr_in server_addr;
3 int client_socket;
4
5 // 创建UDP套接字
6 client_socket = socket(AF_INET, SOCK_DGRAM, 0);
7
8 memset(&server_addr, 0, sizeof(server_addr));
9 server_addr.sin_family = AF_INET;
0 server_addr.sin_addr.s_addr = inet_addr(SERVER_IP);
1 server_addr.sin_port = htons(SERVER_PORT);
2
3 // 发送加入群聊消息
4 sendto(client_socket, "JOIN", strlen("JOIN"), 0, (struct sockaddr *)&server_addr, sizeof(server_addr));
5
6 char buffer[1024];
7
8 while (1) {
9 // 输入消息
0 printf("Enter message to send (type 'EXIT' to leave): ");
1 fgets(buffer, sizeof(buffer), stdin);
2
3 // 发送消息
4 sendto(client_socket, buffer, strlen(buffer), 0, (struct sockaddr *)&server_addr, sizeof(server_addr));
5
6 // 接收消息
7 int bytes_received = recvfrom(client_socket, buffer, sizeof(buffer), 0, NULL, NULL);
8 buffer[bytes_received] = '\0';
9
0 // 打印接收到的消息
1 printf("Received: %s\n", buffer);
2
3 // 检查是否要退出
4 if (strcmp(buffer, "Client has left the chat") == 0) {
5 break;
6 }
7 }
8
9 // 发送退出消息
0 sendto(client_socket, "EXIT", strlen("EXIT"), 0, (struct sockaddr *)&server_addr, sizeof(server_addr));
1
2 close(client_socket);
3
4 return 0;
5 }
6