C语言Socket代码仅16字节缓冲区正常,改为32字节后连接失败原因咨询
问题根因
你遇到的问题本质是未初始化栈内存的随机值导致的偶现可用/不可用,和buffer大小本身没有直接逻辑关联,具体原因如下:
- 客户端代码中,
struct sockaddr_in serv_addr作为局部变量分配在栈内存上,你仅对sin_family、sin_port两个成员做了赋值,没有显式设置sin_addr成员的值,剩下的内存空间是栈上残留的随机垃圾值。 - 当buffer大小设为16时,栈内存的排布刚好让
serv_addr.sin_addr对应的垃圾值是合法的回环地址(127.0.0.1),此时connect可以正常和本地运行的服务端完成三次握手。 - 当你把buffer改成32字节后,栈上局部变量的内存偏移发生变化,
serv_addr.sin_addr对应的垃圾值变成了非法/不可达的IP地址,导致connect调用陷入超时等待,无法完成连接建立,因此服务端收不到连接请求,客户端也不会打印"Connected"日志。
修复方案
- 显式初始化serv_addr结构体,并指定合法的服务端IP,修改客户端代码如下:
首先添加缺失的头文件:
#include <arpa/inet.h>
在connect调用前补充初始化和IP设置逻辑:
// 先清空结构体避免垃圾值干扰 memset(&serv_addr, 0, sizeof(serv_addr)); // 再逐一赋值各成员 serv_addr.sin_family = AF_INET; serv_addr.sin_port = htons(portno); // 连接本地服务端设为回环地址,远程服务端替换为对应IP即可 serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
- 建议给connect调用添加更详细的错误打印,方便定位问题:
if (connect(sock, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) { perror("connect failed"); return -1; }
额外注意点
你当前的服务端代码在accept成功后没有任何写入逻辑,客户端的read(sock, buffer, 16)调用会一直阻塞等待服务端发送数据,后续做数据发送功能时需要补充服务端的write逻辑。
内容的提问来源于stack exchange,提问作者user13931033
相关产品推荐
相关产品推荐

