UDP INET Socket通信异常:客户端recvfrom阻塞无响应
问题排查:UDP客户端卡在
recvfrom无法接收服务端回复 我在实现UDP INET Socket通信时,客户端能成功向服务端发送消息,服务端也能收到,但服务端回复后,客户端终端没有输出,程序卡在recvfrom调用处。请帮忙排查问题。
服务端代码
int main() { int udp_socket = socket(AF_INET, SOCK_DGRAM, 0); struct sockaddr_in adres; adres.sin_addr.s_addr = INADDR_ANY; adres.sin_port = htons(2001); adres.sin_family = AF_INET; int bind_socket = bind(udp_socket, (struct sockaddr*) &adres, sizeof(adres)); if (bind_socket == -1) { perror("Bind"); return 0; } char msg[50]; char msg1[50]; strcpy(msg1, "Sending to client!"); int rcv = recvfrom(udp_socket, msg, sizeof(msg), 0, (struct sockaddr *)&adres, (socklen_t *)sizeof(adres)); int sending = sendto(udp_socket, msg1, sizeof(msg1), 0, (struct sockaddr *)&adres, sizeof(adres)); close(udp_socket); return 0; }
客户端代码
int main() { int udp_socket = socket(AF_INET, SOCK_DGRAM, 0); if(udp_socket < 0) { perror("Socket"); } struct sockaddr_in adres; adres.sin_addr.s_addr = INADDR_ANY; adres.sin_port = htons(2001); adres.sin_family = AF_INET; char msg[50]; strcpy(msg, "Sending to server!"); int sendx = sendto(udp_socket, msg, 50, 0, (struct sockaddr*) &adres, sizeof(adres)); char rcvmsg[50]; int rcv = recvfrom(udp_socket, rcvmsg, 50, 0, (struct sockaddr*) &adres, (socklen_t*) sizeof(adres)); printf("%s:\n", rcvmsg); close(udp_socket); return 0; }
问题分析与解决方案
核心问题
服务端recvfrom的最后一个参数传递错误:recvfrom要求传入指向socklen_t变量的指针,用来存储发送方地址的实际长度。你直接传了(socklen_t *)sizeof(adres),这相当于把一个整数的地址强转过去,会导致adres的内容被破坏,服务端回复时用的是错误的客户端地址,所以客户端永远收不到回复,卡在recvfrom。
其他问题及修正
服务端
- 新增
socklen_t addr_len = sizeof(adres);,将&addr_len作为recvfrom的最后一个参数。 - 检查
recvfrom和sendto的返回值,及时处理错误。 - 给接收的字符串添加结束符,避免乱码。
sendto时用strlen(msg1)代替sizeof(msg1),减少不必要的字节发送。
- 新增
客户端
- 将
adres.sin_addr.s_addr改为服务端的实际IP(比如本地测试用inet_addr("127.0.0.1")),INADDR_ANY不适合作为客户端的目标地址。 - 同样检查
sendto和recvfrom的返回值。 - 给接收的字符串添加结束符,修正
printf的格式。
- 将
修正后的代码
服务端
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/socket.h> #include <netinet/in.h> int main() { int udp_socket = socket(AF_INET, SOCK_DGRAM, 0); if (udp_socket == -1) { perror("socket"); return 1; } struct sockaddr_in adres; memset(&adres, 0, sizeof(adres)); adres.sin_addr.s_addr = INADDR_ANY; adres.sin_port = htons(2001); adres.sin_family = AF_INET; int bind_socket = bind(udp_socket, (struct sockaddr*) &adres, sizeof(adres)); if (bind_socket == -1) { perror("Bind"); close(udp_socket); return 1; } char msg[50]; char msg1[50] = "Sending to client!"; socklen_t addr_len = sizeof(adres); int rcv = recvfrom(udp_socket, msg, sizeof(msg)-1, 0, (struct sockaddr *)&adres, &addr_len); if (rcv == -1) { perror("recvfrom"); close(udp_socket); return 1; } msg[rcv] = '\0'; printf("Received from client: %s\n", msg); int sending = sendto(udp_socket, msg1, strlen(msg1), 0, (struct sockaddr *)&adres, addr_len); if (sending == -1) { perror("sendto"); close(udp_socket); return 1; } close(udp_socket); return 0; }
客户端
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> int main() { int udp_socket = socket(AF_INET, SOCK_DGRAM, 0); if(udp_socket == -1) { perror("Socket"); return 1; } struct sockaddr_in adres; memset(&adres, 0, sizeof(adres)); adres.sin_addr.s_addr = inet_addr("127.0.0.1"); adres.sin_port = htons(2001); adres.sin_family = AF_INET; char msg[50] = "Sending to server!"; int sendx = sendto(udp_socket, msg, strlen(msg), 0, (struct sockaddr*) &adres, sizeof(adres)); if (sendx == -1) { perror("sendto"); close(udp_socket); return 1; } char rcvmsg[50]; socklen_t addr_len = sizeof(adres); int rcv = recvfrom(udp_socket, rcvmsg, sizeof(rcvmsg)-1, 0, (struct sockaddr*) &adres, &addr_len); if (rcv == -1) { perror("recvfrom"); close(udp_socket); return 1; } rcvmsg[rcv] = '\0'; printf("Received from server: %s\n", rcvmsg); close(udp_socket); return 0; }
内容的提问来源于stack exchange,提问作者Halaviw
相关产品推荐
相关产品推荐

