UDP回显服务器sendto返回-1,提示Address family not supported问题求助
解决sendto返回-1并提示"Address family not supported"的问题
看起来你遇到的问题大概率和客户端地址结构体的初始化/使用不当有关,这个错误通常意味着sendto调用时传入的目标地址结构体(也就是你的cli_addr)的地址族字段是无效值。咱们一步步来排查和修复:
核心原因及解决方案
1. cli_addr未初始化 + recvfrom前未设置addr_len初始值
recvfrom的最后一个参数是传入传出参数:调用前必须把它设置为目标地址结构体的大小(也就是sizeof(cli_addr)),否则系统无法正确填充客户端的地址信息。另外,如果cli_addr没有清零初始化,内存里的垃圾数据会干扰地址族字段的正确性,直接导致sendto报错。
你需要在调用recvfrom之前添加这两行代码:
memset(&cli_addr, 0, sizeof(cli_addr)); // 清零初始化客户端地址结构体 addr_len = sizeof(cli_addr); // 设置地址长度的初始值
2. 发送长度用错了(非致命但建议修正)
虽然这不会直接导致地址族错误,但也是常见的小问题:你现在用BUFF_SIZE作为发送长度,正确的做法应该是用recvfrom返回的实际接收长度ret,否则会把缓冲区里的垃圾数据也一并发送给客户端。
修正后的完整代码片段
把这些修改整合到你的代码里,大概是这样:
// ... 之前的socket创建、bind代码保持不变 ... // 初始化客户端地址结构体和地址长度(这部分是新增的关键代码) struct sockaddr_in cli_addr; socklen_t addr_len; memset(&cli_addr, 0, sizeof(cli_addr)); addr_len = sizeof(cli_addr); ret = recvfrom(sock, buff, BUFF_SIZE, 0, (struct sockaddr *)&cli_addr, &addr_len); if (ret < 0) { perror("recvfrom"); exit(EXIT_FAILURE); } printf("%d received:\n\t%s\n", ret, buff); printf("Sending:\n\t%s\n", buff); // 用实际接收长度ret作为发送长度,替代原有的BUFF_SIZE ret = sendto(sock, buff, ret, 0, (struct sockaddr *)&cli_addr, addr_len); if (ret < 0) { perror("sendto"); exit(EXIT_FAILURE); } printf("%d char sent\n", ret); close(sock);
额外排查点(如果上述修改无效)
- 确认
cli_addr确实被定义为struct sockaddr_in,而非其他不匹配的类型(比如struct sockaddr,虽然强制转换可行,但初始化和长度设置必须对应)。 - 检查编译时的警告信息,确保
addr_len的类型是标准的socklen_t(部分旧系统可能用int,但推荐遵循POSIX标准)。
内容的提问来源于stack exchange,提问作者foo




