#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <pthread.h>
#define BUFFER_SIZE 1024
#define EXIT_MESSAGE "exit"
#define THREAD_POOL_SIZE 5
typedef struct {
int client_socket;
int client_id;
} ClientInfo;
typedef struct {
ClientInfo **clients;
int client_count;
int thread_count;
pthread_mutex_t mutex;
pthread_cond_t condition;
int is_running;
} ThreadPool;
void error(const char *message) {
perror(message);
exit(1);
}
void *handle_client(void *arg) {
ClientInfo *client_info = (ClientInfo *)arg;
int client_socket = client_info->client_socket;
int client_id = client_info->client_id;
char buffer[BUFFER_SIZE];
while (1) {
// 接收客户端消息
memset(buffer, 0, sizeof(buffer));
if (recv(client_socket, buffer, sizeof(buffer), 0) < 0) {
error("Error receiving data");
}
printf("Received message from client %d: %s\n", client_id, buffer);
// 去除换行符
buffer[strcspn(buffer, "\n")] = '\0';
// 检查退出消息
if (strcmp(buffer, EXIT_MESSAGE) == 0) {
printf("Client %d disconnected\n", client_id);
break;
}
// 处理客户端请求(这里只是回显)
if (send(client_socket, buffer, strlen(buffer), 0) < 0) {
error("Error sending data");
}
}
// 关闭客户端套接字
close(client_socket);
free(client_info);
pthread_exit(NULL);
}
void *manager_thread(void *arg) {
ThreadPool *thread_pool = (ThreadPool *)arg;
while (thread_pool->is_running) {
// 检查任务队列中的任务数量和工作线程个数
pthread_mutex_lock(&thread_pool->mutex);
int task_count = thread_pool->client_count;
int working_threads = thread_pool->thread_count;
pthread_mutex_unlock(&thread_pool->mutex);
printf("Task count: %d, Working threads: %d\n", task_count, working_threads);
// 适当调整线程池大小
if (task_count > working_threads && working_threads < THREAD_POOL_SIZE) {
// 创建新的工作线程
pthread_t thread;
if (pthread_create(&thread, NULL, handle_client, thread_pool->clients[task_count - 1]) != 0) {
error("Error creating thread");
}
thread_pool->thread_count++;
} else if (task_count < working_threads && working_threads > 1) {
// 销毁一个工作线程
pthread_mutex_lock(&thread_pool->mutex);
int index = thread_pool->thread_count - 1;
pthread_mutex_unlock(&thread_pool->mutex);
pthread_join(thread_pool->threads[index], NULL);
thread_pool->thread_count--;
}
// 等待一段时间再次检查
sleep(2);
}
pthread_exit(NULL);
}
int main(int argc, char *argv[]) {
if (argc != 2) {
fprintf(stderr, "Usage: %s <port>\n", argv[0]);
exit(1);
}
int server_socket, client_socket;
char buffer[BUFFER_SIZE];
struct sockaddr_in server_addr, client_addr;
socklen_t client_addr_len;
// 创建服务器套接字
server_socket = socket(AF_INET, SOCK_STREAM, 0);
if (server_socket < 0) {
error("Error opening socket");
}
// 设置服务器地址结构
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = INADDR_ANY;
server_addr.sin_port = htons(atoi(argv[1]));
// 绑定服务器套接字到指定端口
if (bind(server_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
error("Error binding socket");
}
// 监听连接请求
if (listen(server_socket, 5) < 0) {
error("Error listening");
}
printf("Waiting for connections...\n");
ThreadPool thread_pool;
thread_pool.clients = (ClientInfo **)malloc(sizeof(ClientInfo *) * THREAD_POOL_SIZE);
thread_pool.client_count = 0;
thread_pool.thread_count = 0;
pthread_mutex_init(&thread_pool.mutex, NULL);
pthread_cond_init(&thread_pool.condition, NULL);
thread_pool.is_running = 1;
pthread_t manager_thread_id;
if (pthread_create(&manager_thread_id, NULL, manager_thread, &thread_pool) != 0) {
error("Error creating manager thread");
}
while (1) {
// 接受客户端连接
client_addr_len = sizeof(client_addr);
client_socket = accept(server_socket, (struct sockaddr *)&client_addr, &client_addr_len);
if (client_socket < 0) {
error("Error accepting connection");
}
printf("Client connected\n");
// 创建客户端信息结构体
ClientInfo *client_info = (ClientInfo *)malloc(sizeof(ClientInfo));
client_info->client_socket = client_socket;
pthread_mutex_lock(&thread_pool.mutex);
// 将客户端信息添加到任务队列中
if (thread_pool.client_count < THREAD_POOL_SIZE) {
client_info->client_id = thread_pool.client_count + 1;
thread_pool.clients[thread_pool.client_count++] = client_info;
pthread_cond_signal(&thread_pool.condition);
} else {
// 线程池已满,拒绝连接
printf("Thread pool is full. Connection rejected.\n");
close(client_socket);
free(client_info);
}
pthread_mutex_unlock(&thread_pool.mutex);
}
// 停止线程池运行
thread_pool.is_running = 0;
pthread_cond_broadcast(&thread_pool.condition);
// 等待管理者线程结束
pthread_join(manager_thread_id, NULL);
// 等待线程池中的线程结束
for (int i = 0; i < thread_pool.client_count; i++) {
pthread_join(thread_pool.threads[i], NULL);
}
// 关闭服务器套接字
close(server_socket);
pthread_mutex_destroy(&thread_pool.mutex);
pthread_cond_destroy(&thread_pool.condition);
// 释放内存
for (int i = 0; i < thread_pool.client_count; i++) {
free(thread_pool.clients[i]);
}
free(thread_pool.clients);
return 0;
}