运行TCP客户端时出现Connection refused错误的技术求助
问题分析与解决方案
核心问题
C客户端代码中,服务器端口号未转换为网络字节序,导致连接请求发送到错误端口,触发Connection refused(errno 111)错误。浏览器能正常连接是因为浏览器内部自动完成了字节序转换,而C代码需要手动处理。
修复步骤
1. 修正端口字节序转换
在client_init()函数中,将端口赋值语句修改为:
server_addr.sin_port = htons(SERVER_PORT);
htons()函数负责将主机字节序的端口号转换为TCP/IP协议要求的网络字节序(大端模式),这是TCP客户端建立连接的必要步骤。
2. 优化TCP数据发送逻辑
TCP连接建立后无需使用sendto()(该函数多用于UDP),改用send()即可,同时避免发送缓冲区中的空白字符:
if (send(client_fd, buffer, strlen(buffer), 0) == -1) { perror("send error"); exit(1); }
完整修正后的C客户端代码
#include <stdio.h> #include <string.h> #include <arpa/inet.h> #include <netinet/in.h> #include <stdlib.h> #include <errno.h> #include <unistd.h> #define SERVER_IP "127.0.0.1" /* 服务器IP地址(点分十进制) */ #define SERVER_PORT 5566 /* 服务器端口号 */ #define BUF_SIZE 1024 /* 数据传输缓冲区大小 */ static int client_fd; /* 客户端套接字文件描述符 */ static struct sockaddr_in server_addr; /* 服务器套接字地址结构体 */ static void client_init() { /* 创建客户端套接字 */ client_fd = socket(AF_INET, SOCK_STREAM, 0); if (client_fd == -1) { perror("socket error"); exit(errno); } /* 初始化服务器地址结构体 */ server_addr.sin_family = AF_INET; server_addr.sin_port = htons(SERVER_PORT); /* 转换为网络字节序端口 */ server_addr.sin_addr.s_addr = inet_addr(SERVER_IP); /* 发起服务器连接 */ if (connect(client_fd, (struct sockaddr *)(&server_addr), sizeof(server_addr)) == -1) { perror("connect error"); exit(errno); } } int main() { FILE *file; char buffer[BUF_SIZE]; file = fopen("./client.txt", "r"); if (file == NULL) { perror("fopen error"); exit(errno); } client_init(); while (fgets(buffer, BUF_SIZE, file) != NULL) { if (send(client_fd, buffer, strlen(buffer), 0) == -1) { perror("send error"); exit(1); } memset(buffer, 0, BUF_SIZE); // 清空缓冲区 } fclose(file); close(client_fd); // 关闭套接字 return 0; }
Python服务端优化建议
当前服务端每次接收数据都会覆盖server.txt,若需追加内容,修改文件打开模式为ab;同时增加客户端断开检测:
import socket import threading SERVER_IP = "127.0.0.1" SERVER_PORT = 5566 SERVER_ADDR = (SERVER_IP, SERVER_PORT) PACKET_SIZE = 1024 server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server.bind(SERVER_ADDR) def client_handler(client, client_addr): print(f"[NEW CONNECTION] {client_addr}") with open('./server.txt', 'ab') as file: while True: packet = client.recv(PACKET_SIZE) if not packet: # 客户端断开时recv返回空 break file.write(packet) print(f"[CONNECTION CLOSED] {client_addr}") client.close() def server_init(): print(f"Listening on {SERVER_PORT}") server.listen() while True: client, client_addr = server.accept() thread = threading.Thread(target=client_handler, args=(client, client_addr)) thread.start() print(f"[ACTIVE CONNECTION] {threading.active_count() - 1}") print("Starting server...") server_init()
内容的提问来源于stack exchange,提问作者Yiyang Yan
相关产品推荐
相关产品推荐

