用c语言写一个基于socket的多人聊天室
时间: 2023-09-05 16:11:18 浏览: 113
好的,下面是一个简单的基于socket的多人聊天室的C语言实现。这个聊天室支持多个客户端同时连接,每个客户端可以发送聊天消息给其他客户端,同时也可以接收其他客户端发送的聊天消息。这个聊天室还包括一些基本的错误处理和异常情况的处理,例如客户端断开连接等。
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <pthread.h>
#define MAX_CLIENTS 10
#define BUF_SIZE 1024
int client_sockets[MAX_CLIENTS];
int num_clients = 0;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
void *client_handler(void *arg) {
int client_fd = *(int *)arg;
char buf[BUF_SIZE];
int num_bytes;
int i;
printf("Client %d connected.\n", client_fd);
while ((num_bytes = recv(client_fd, buf, BUF_SIZE, 0)) > 0) {
buf[num_bytes] = '\0';
pthread_mutex_lock(&mutex);
for (i = 0; i < num_clients; i++) {
if (client_sockets[i] != client_fd) {
send(client_sockets[i], buf, num_bytes, 0);
}
}
pthread_mutex_unlock(&mutex);
}
pthread_mutex_lock(&mutex);
for (i = 0; i < num_clients; i++) {
if (client_sockets[i] == client_fd) {
client_sockets[i] = 0;
}
}
num_clients--;
pthread_mutex_unlock(&mutex);
printf("Client %d disconnected.\n", client_fd);
close(client_fd);
pthread_exit(NULL);
}
int main(int argc, char *argv[]) {
int server_fd, client_fd;
struct sockaddr_in server_addr, client_addr;
socklen_t client_len;
pthread_t thread_id;
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("socket");
exit(1);
}
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(1234);
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(server_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) {
perror("bind");
exit(1);
}
if (listen(server_fd, MAX_CLIENTS) == -1) {
perror("listen");
exit(1);
}
printf("Chat room started.\n");
while (1) {
client_len = sizeof(client_addr);
if ((client_fd = accept(server_fd, (struct sockaddr *)&client_addr, &client_len)) == -1) {
perror("accept");
continue;
}
if (num_clients >= MAX_CLIENTS) {
printf("Too many clients. Connection refused.\n");
close(client_fd);
continue;
}
pthread_mutex_lock(&mutex);
client_sockets[num_clients++] = client_fd;
pthread_mutex_unlock(&mutex);
pthread_create(&thread_id, NULL, client_handler, &client_fd);
pthread_detach(thread_id);
}
close(server_fd);
return 0;
}
```
这个聊天室使用了一个数组 `client_sockets` 来保存所有已连接的客户端的 socket 描述符,同时使用了一个互斥锁 `mutex` 来保护这个数组的读写操作。当一个新客户端连接时,它会被加入到 `client_sockets` 数组中,并启动一个新线程来处理该客户端的聊天消息。在每个线程中,使用 `recv` 函数来接收客户端发送的聊天消息,并使用 `send` 函数将消息广播给其他客户端。当客户端断开连接时,它会从 `client_sockets` 数组中移除,并关闭连接。
该聊天室使用了一个简单的文本协议,即每个消息都是一行文本,以换行符 `\n` 结尾。客户端发送消息时,只需要将文本发送到服务器端即可,服务器端会自动将消息广播给所有其他客户端。
阅读全文