【问题标题】:Sockets UDP: Using Sender Info from Recvfrom() in Sendto() Fails套接字 UDP:在 Sendto() 中使用来自 Recvfrom() 的发件人信息失败
【发布时间】:2012-04-19 21:36:41
【问题描述】:

我正在尝试编写一个通过 UDP 接收查询并通过 UDP 发送响应的服务器。我遇到的问题是,当我尝试发送响应时,我收到“101 网络无法访问”错误。

基于here 的问题,我尝试通过删除hints.ai_flags = AI_PASSIVE; 行来解决此问题,但随后服务器从未成功获取消息。我查看了addrinfo 的手册页,听起来如果设置了AI_PASSIVE 标志,则套接字只能recvfrom(),而如果未设置,则套接字只能sendto()。不过,我在网上看到了很多例子,人们都从一个套接字同时做这件事;我错过了什么?

相关代码:

struct addrinfo hints;
struct addrinfo *serverinfo;
memset(&hints,0,sizeof hints);
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_flags = AI_PASSIVE;

int status = getaddrinfo(NULL, port, &hints, &serverinfo);
int sock = socket(serverinfo->ai_family, serverinfo->ai_socktype, serverinfo->ai_protocol);
status = bind(sock, serverinfo->ai_addr, serverinfo->ai_addrlen);
freeaddrinfo(serverinfo);

// poll until there's an incoming packet

struct sockaddr sender;
socklen_t sendsize = sizeof(sender);
bzero(&sender, sizeof(sender));

recvfrom(sock, message, sizeof(message), 0, &sender, &sendsize);

// message processing

sendto(sock, response, sizeof(response), 0, (struct sockaddr *)&sender, sendsize);

是的,我对所有这些调用进行了错误检查(这就是我发现问题的方式);为了简洁起见,它被简单地忽略了。

【问题讨论】:

  • 我系统上的getaddrinfo(3) 页面显示在调用getaddrinfo(3) 之前正在初始化hints.ai_protocolhints.ai_canonnamehints.ai_addrhints.ad_next。这些可能很重要,请尝试初始化它们。 (当然,你将整个结构归零;这就是为什么这只是一个评论......)
  • 两种方式都出现同样的错误吗?含义 A->B->A(Get error) 和 B->A->B(get error?)

标签: c sockets udp


【解决方案1】:

您不应该使用struct sockaddr 来存储recvfrom 调用中的源地址,它可能无法表示IP 套接字地址。

您应该对 IPv4 地址使用 struct sockaddr_in 或对 IPv6 地址使用 struct sockaddr_in6,或者更好的是使用 struct sockaddr_storage 来处理两者。

struct sockaddr_storage sender;
socklen_t sendsize = sizeof(sender);
bzero(&sender, sizeof(sender));

recvfrom(sock, message, sizeof(message), 0, (struct sockaddr*)&sender, &sendsize);

【讨论】:

    猜你喜欢
    • 2011-04-25
    • 2016-01-07
    • 2022-11-24
    • 2020-06-08
    • 2011-02-09
    • 2011-09-05
    • 2015-07-27
    • 2018-05-12
    • 1970-01-01
    相关资源
    最近更新 更多