写一个服务器和两个客户端
运行服务器和2个客户端,实现聊天功能
客户端1 和 客户端2 进行聊天
客户端1将聊天数据发送给服务器
服务器将聊天数据转发给客户端2
要求: 服务器使用 select 模型实现 客户端1使用 poll 模型实现 客户端2使用 多线程实现
服务器:
cs
1
2 #include "head.h"
3
4 #define PORT 12345
5 #define MAX_CLIENTS 10
6 #define BUFFER_SIZE 1024
7
8 void handle_client_message(int client_sock, int *clients, int num_clients) {
9 char buffer[BUFFER_SIZE];
0 int bytes_received = recv(client_sock, buffer, sizeof(buffer), 0);
1 if (bytes_received <= 0) {
2 close(client_sock);
3 for (int i = 0; i < num_clients; i++) {
4 if (clients[i] == client_sock) {
5 clients[i] = clients[num_clients - 1];
6 break;
7 }
8 }
9 return;
0 }
1 buffer[bytes_received] = '\0';
2 printf("Received message: %s\n", buffer);
3
4 // 广播消息给所有其他客户端
5 for (int i = 0; i < num_clients; i++) {
6 if (clients[i] != client_sock) {
7 send(clients[i], buffer, strlen(buffer), 0);
8 }
9 }
0 }
1
2 void server() {
3 int server_sock, client_sock, max_fd;
4 struct sockaddr_in server_addr, client_addr;
5 socklen_t client_len = sizeof(client_addr);
6 fd_set read_fds, temp_fds;
7 int clients[MAX_CLIENTS];
8 int num_clients = 0;
9
0 // 创建服务器socket
1 server_sock = socket(AF_INET, SOCK_STREAM, 0);
2 if (server_sock < 0) {
3 perror("Socket creation failed");
4 exit(EXIT_FAILURE);
5 }
6
7 // 绑定服务器地址
8 memset(&server_addr, 0, sizeof(server_addr));
9 server_addr.sin_family = AF_INET;
0 server_addr.sin_addr.s_addr = INADDR_ANY;
1 server_addr.sin_port = htons(PORT);
2
3 if (bind(server_sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
4 perror("Binding failed");
5 exit(EXIT_FAILURE);
6 }
7
8 // 监听客户端连接
9 listen(server_sock, 5);
0 FD_ZERO(&read_fds);
1 FD_SET(server_sock, &read_fds);
2 max_fd = server_sock;
3
4 printf("Server listening on port %d...\n", PORT);
5
6 while (1) {
7 temp_fds = read_fds;
8
9 // 使用select等待活动的socket
0 if (select(max_fd + 1, &temp_fds, NULL, NULL, NULL) < 0) {
1 perror("Select error");
2 exit(EXIT_FAILURE);
3 }
4
5 // 检查所有客户端连接
6 for (int i = 0; i <= max_fd; i++) {
7 if (FD_ISSET(i, &temp_fds)) {
8 if (i == server_sock) {
9 // 有新的客户端连接
0 client_sock = accept(server_sock, (struct sockaddr *)&client_addr, &client_len);
1 if (client_sock < 0) {
2 perror("Accept failed");
3 continue;
4 }
5 printf("New connection: %d\n", client_sock);
6
7 FD_SET(client_sock, &read_fds);
8 clients[num_clients++] = client_sock;
9 if (client_sock > max_fd) {
0 max_fd = client_sock;
1 }
2 } else {
3 // 处理现有客户端的消息
4 handle_client_message(i, clients, num_clients);
5 }
6 }
7 }
8 }
9
0 close(server_sock);
1 }
2
3 int main() {
4 server();
5 return 0;
6 }
7
客户端1:
cs
#include "head.h"
#define PORT 12345
#define BUFFER_SIZE 1024
void client1() {
int sock;
struct sockaddr_in server_addr;
struct pollfd fds[2];
char buffer[BUFFER_SIZE];
// 创建客户端socket
sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0) {
perror("Socket creation failed");
exit(EXIT_FAILURE);
}
// 设置服务器地址
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
server_addr.sin_port = htons(PORT);
// 连接到服务器
if (connect(sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
perror("Connection failed");
exit(EXIT_FAILURE);
}
printf("Connected to server. Type your messages.\n");
// 设置poll结构
fds[0].fd = sock; // 服务器socket
fds[0].events = POLLIN;
fds[1].fd = STDIN_FILENO; // 标准输入
fds[1].events = POLLIN;
while (1) {
// 使用poll模型
int ret = poll(fds, 2, -1);
if (ret < 0) {
perror("Poll failed");
exit(EXIT_FAILURE);
}
if (fds[0].revents & POLLIN) {
// 服务器发送消息
int n = recv(sock, buffer, sizeof(buffer), 0);
if (n <= 0) {
printf("Server disconnected\n");
break;
}
buffer[n] = '\0';
printf("Server: %s\n", buffer);
}
if (fds[1].revents & POLLIN) {
// 用户输入消息
if (fgets(buffer, sizeof(buffer), stdin) != NULL) {
send(sock, buffer, strlen(buffer), 0);
}
}
}
close(sock);
}
int main() {
client1();
return 0;
}
客户端2:
cs
#include "head.h"
#define PORT 12345
#define BUFFER_SIZE 1024
void *receive_messages(void *socket_desc) {
int sock = *(int *)socket_desc;
char buffer[BUFFER_SIZE];
while (1) {
int n = recv(sock, buffer, sizeof(buffer), 0);
if (n <= 0) {
printf("Server disconnected\n");
break;
}
buffer[n] = '\0';
printf("Server: %s\n", buffer);
}
return NULL;
}
void client2() {
int sock;
struct sockaddr_in server_addr;
pthread_t thread_id;
char buffer[BUFFER_SIZE];
// 创建客户端socket
sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0) {
perror("Socket creation failed");
exit(EXIT_FAILURE);
}
// 设置服务器地址
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
server_addr.sin_port = htons(PORT);
// 连接到服务器
if (connect(sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
perror("Connection failed");
exit(EXIT_FAILURE);
}
printf("Connected to server. Type your messages.\n");
// 创建接收消息线程
if (pthread_create(&thread_id, NULL, receive_messages, (void *)&sock) < 0) {
perror("Could not create thread");
exit(EXIT_FAILURE);
}
// 发送消息
while (1) {
fgets(buffer, sizeof(buffer), stdin);
send(sock, buffer, strlen(buffer), 0);
}
close(sock);
}
int main() {
client2();
return 0;
}
结果:
