C语言写基于TCP协议的简易聊天机器人多线程服务器
时间: 2023-07-14 21:13:23 浏览: 142
好的,下面是一个基于TCP协议的简易聊天机器人多线程服务器的C语言实现:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <pthread.h>
#define MAX_CLIENTS 10
#define MAX_MESSAGE_LEN 1024
// 客户端信息
struct client_info {
int sockfd;
struct sockaddr_in addr;
};
// 消息缓冲区
char message_buffer[MAX_MESSAGE_LEN];
// 机器人回复
const char *robot_response(const char *message) {
// 在这里实现机器人的回复逻辑
return "Hello, I'm a chatbot!";
}
// 处理客户端连接的函数
void *handle_client(void *arg) {
struct client_info *info = (struct client_info *) arg;
int sockfd = info->sockfd;
struct sockaddr_in addr = info->addr;
free(info); // 释放客户端信息结构体的内存
printf("New client connected: %s:%d\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
// 发送欢迎消息
const char *welcome_message = "Welcome to my chat server!\n";
if (send(sockfd, welcome_message, strlen(welcome_message), 0) < 0) {
perror("send");
close(sockfd);
return NULL;
}
// 不断接收客户端发送的消息,并回复
while (1) {
int message_len = recv(sockfd, message_buffer, MAX_MESSAGE_LEN, 0);
if (message_len < 0) {
perror("recv");
break;
} else if (message_len == 0) {
printf("Client disconnected: %s:%d\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
break;
}
// 处理收到的消息
message_buffer[message_len] = '\0';
printf("Received message from %s:%d: %s", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port), message_buffer);
// 回复消息
const char *response = robot_response(message_buffer);
if (send(sockfd, response, strlen(response), 0) < 0) {
perror("send");
break;
}
}
close(sockfd);
return NULL;
}
int main() {
int server_sockfd, client_sockfd;
struct sockaddr_in server_addr, client_addr;
socklen_t client_addr_len = sizeof(client_addr);
pthread_t client_threads[MAX_CLIENTS];
int num_clients = 0;
// 创建服务器套接字
if ((server_sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
perror("socket");
return 1;
}
// 绑定服务器地址和端口
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = INADDR_ANY;
server_addr.sin_port = htons(8888);
if (bind(server_sockfd, (struct sockaddr *) &server_addr, sizeof(server_addr)) < 0) {
perror("bind");
return 1;
}
// 监听客户端连接
if (listen(server_sockfd, MAX_CLIENTS) < 0) {
perror("listen");
return 1;
}
printf("Server started on port 8888.\n");
// 不断接受客户端连接
while (1) {
// 等待客户端连接
if ((client_sockfd = accept(server_sockfd, (struct sockaddr *) &client_addr, &client_addr_len)) < 0) {
perror("accept");
continue;
}
// 创建新的线程处理客户端连接
struct client_info *info = malloc(sizeof(struct client_info));
info->sockfd = client_sockfd;
info->addr = client_addr;
pthread_create(&client_threads[num_clients], NULL, handle_client, info);
num_clients++;
if (num_clients >= MAX_CLIENTS) {
printf("Maximum number of clients reached. No longer accepting new connections.\n");
break;
}
}
// 等待所有客户端线程退出
for (int i = 0; i < num_clients; i++) {
pthread_join(client_threads[i], NULL);
}
close(server_sockfd);
return 0;
}
```
这个服务器程序使用了多线程来处理不同的客户端连接,每当一个客户端连接到服务器时,就会创建一个新的线程来处理这个客户端的连接。在主线程中,程序会不断地接受新的客户端连接,直到达到最大连接数为止。
每个客户端连接的处理逻辑都在 `handle_client` 函数中实现。在这个函数中,程序会先发送一个欢迎消息给客户端,然后进入一个循环,不断接收客户端发送的消息,并回复机器人的回复。
在 `robot_response` 函数中,你可以实现机器人的回复逻辑,根据客户端发送的消息来生成机器人的回复。该函数的返回值即为机器人回复的内容。
阅读全文