#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <errno.h>
#define MAX_SIZE 2048
#define SERVER_PORT 8000
// 工作线程函数:处理单个客户端的阻塞 I/O
void* handle_client(void* arg) {
int client_fd = (long)arg;
pthread_detach(pthread_self()); // 自动回收线程资源
long thread_id = (long)pthread_self();
printf("Thread %ld: Started, handling client socket %d\n", thread_id, client_fd);
char buffer[MAX_SIZE];
ssize_t recv_len;
// 阻塞循环读取
while ((recv_len = recv(client_fd, buffer, MAX_SIZE - 1, 0)) > 0) {
buffer[recv_len] = '\0';
printf("Thread %ld: Received %zd bytes from %d: %s",
thread_id, recv_len, client_fd, buffer);
// 回显给客户端
ssize_t sent = send(client_fd, buffer, recv_len, 0);
if (sent < 0) {
perror("send failed");
break;
}
printf("Thread %ld: Sent %zd bytes back to client %d\n",
thread_id, sent, client_fd);
}
// recv 返回 0:客户端正常关闭连接
if (recv_len == 0) {
printf("Thread %ld: Client %d disconnected gracefully.\n", thread_id, client_fd);
}
// recv 返回 -1:错误
else {
if (errno == ECONNRESET) {
printf("Thread %ld: Client %d forced close (RST).\n", thread_id, client_fd);
} else {
perror("recv error");
}
}
// 关闭客户端 socket
close(client_fd);
printf("Thread %ld: Closed socket %d and exiting.\n", thread_id, client_fd);
return NULL;
}
int main() {
int server_fd;
struct sockaddr_in server_addr, client_addr;
socklen_t client_len = sizeof(client_addr);
// 创建 socket
server_fd = socket(AF_INET, SOCK_STREAM, 0);
if (server_fd < 0) {
perror("socket creation failed");
exit(EXIT_FAILURE);
}
// 设置端口复用,避免 "Address already in use"
int opt = 1;
setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
// 绑定地址
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(SERVER_PORT);
if (bind(server_fd, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) {
perror("bind failed");
close(server_fd);
exit(EXIT_FAILURE);
}
// 监听
if (listen(server_fd, 10) < 0) {
perror("listen failed");
close(server_fd);
exit(EXIT_FAILURE);
}
printf("TCP Server started on port %d\n", SERVER_PORT);
printf("Waiting for incoming connections...\n");
// 主循环:accept 客户端并创建线程
while (1) {
int client_fd = accept(server_fd, (struct sockaddr*)&client_addr, &client_len);
if (client_fd < 0) {
perror("accept failed");
continue; // 继续监听
}
// 获取客户端 IP
char client_ip[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &client_addr.sin_addr, client_ip, INET_ADDRSTRLEN);
int client_port = ntohs(client_addr.sin_port);
printf("Accepted connection from %s:%d (socket %d)\n",
client_ip, client_port, client_fd);
// 创建线程处理该客户端
pthread_t thread_id;
if (pthread_create(&thread_id, NULL, handle_client, (void*)(long)client_fd) != 0) {
perror("pthread_create failed");
printf("Failed to create thread for client %d, closing connection.\n", client_fd);
close(client_fd);
}
// 注意:线程已 detach,无需 join
}
// 正常不会执行到这里
close(server_fd);
return 0;
}