利用线程池和网络动态库实现多人聊天室
概述
本项目实现一个简单的多人聊天室,采用C语言编写,利用线程池和网络动态库,实现服务端消息转发和客户端消息接收。
服务端
服务端主要负责管理客户端连接,接收并转发消息。
代码实现
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <network.h> // 自己封装的网络动态库
#include <pthread.h>
#include "threadpool.h" // 自己封装的线程池工具
#define BUFFER_SIZE 1024
#define MAX_CLIENT 50
// 在线客户端数组
Network *clients[MAX_CLIENT];
// 添加到客户端
int add_clients(Network *nw) {
for (int i = 0; i < MAX_CLIENT; i++) {
if (NULL == clients[i]) {
clients[i] = nw;
return i;
}
}
return -1; // 返回错误状态
}
// 转发消息给其他客户端
void send_clients(int index, char *str) {
for (int i = 0; i < MAX_CLIENT; i++) {
if (NULL != clients[i] && i != index) {
send_nw(clients[i], str, strlen(str) + 1);
}
}
}
// 处理客户端进入聊天室的逻辑
void enter(void *arg) {
int index = add_clients(arg);
char *buf = malloc(BUFFER_SIZE);
// 接收昵称
int ret = recv_nw(clients[index], buf, BUFFER_SIZE);
if (ret <= 0 || 0 == strcmp(buf, "quit")) {
close_nw(clients[index]);
clients[index] = NULL;
free(buf);
return;
}
strcat(buf, "进入了聊天室,大家小心!\n");
send_clients(index, buf);
// 设置昵称后添加冒号
buf[ret - 1] = ':';
char *msg = buf + ret;
// 接收消息
for (;;) {
int ret = recv_nw(clients[index], msg, BUFFER_SIZE);
if (ret <= 0 || 0 == strcmp(msg, "quit\n")) {
sprintf(msg, "离开了聊天室!\n");
send_clients(index, buf);
close_nw(clients[index]);
clients[index] = NULL;
free(buf);
return;
}
send_clients(index, buf);
}
}
int main(int argc, char *argv[]) {
// 检查命令行参数
if (3 != argc) {
printf("Usage: chat_ser <ip> <port>\n");
return EXIT_FAILURE;
}
// 创建线程池
ThreadPool *threadpool = creat_threadpool(50, 20, enter);
start_threadpool(threadpool);
// 启动网络通信
Network *svr_nw = init_nw(SOCK_STREAM, atoi(argv[2]), argv[1], true);
if (NULL == svr_nw) {
printf("Server network init failed!\n");
return EXIT_FAILURE;
}
for (;;) {
// 等待客户端连接
Network *clt_nw = accept_nw(svr_nw);
if (NULL == clt_nw) {
printf("Accept client failed!\n");
continue;
}
// 添加到线程池
push_threadpool(threadpool, clt_nw);
}
}
客户端
客户端负责连接到服务器,并发送和接收消息。
代码实现
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <network.h>
#include <pthread.h>
char buf[1024] = {};
size_t buf_size = sizeof(buf);
void* run(void* arg) {
Network* nw = (Network*)arg;
for (;;) {
int ret = recv_nw(nw, buf, buf_size);
if (ret <= 0) {
puts("服务器正在升级,请检查\n");
exit(EXIT_FAILURE);
}
printf("\r----%s\n", buf);
printf(">>>>>>>>>>");
fflush(stdout);
}
}
int main(int argc, const char* argv[]) {
if (argc != 3) {
printf("Usage: %s <server_ip> <server_port>\n", argv[0]);
return 1;
}
Network* nw = init_nw(SOCK_STREAM, atoi(argv[2]), argv[1], false);
if (nw == NULL) {
printf("网络错误,请检查\n");
return EXIT_FAILURE;
}
printf("请输入你的昵称:");
scanf("%s", buf);
send_nw(nw, buf, strlen(buf) + 1);
pthread_t tid;
pthread_create(&tid, NULL, run, nw);
for (;;) {
printf(">>>>>>>>>");
fgets(buf, sizeof(buf), stdin);
int ret = send_nw(nw, buf, strlen(buf) + 1);
if (0 == strcmp(buf, "quit\n")) {
puts("退出聊天室\n");
return EXIT_SUCCESS;
}
if (ret <= 0) {
puts("服务器正在升级,请检查\n");
return EXIT_FAILURE;
}
}
return 0;
}
总结
此聊天室实现了基本的多人聊天功能,使用服务器转发消息给其他客户端,结合线程池提高并发处理能力。你可以在此基础上扩展更多功能,比如昵称验证、聊天记录保存等。
标签:index,聊天室,int,clients,线程,多人,include,buf,nw From: https://blog.csdn.net/m0_57538342/article/details/142874830