【问题标题】:How to force client in UDP to open port when sending with sendto使用 sendto 发送时如何强制 UDP 中的客户端打开端口
【发布时间】:2012-01-21 13:56:39
【问题描述】:

我在 UDP (WinSocks/C++) 中有简单的服务器和客户端。

我通过sendto发送数据报客户端->服务器,并使用从recvfrom函数获得的ip和端口从服务器回复客户端。

我发现:

  1. 来自客户端的每个 sendto 都从不同的端口发送
  2. 当尝试从服务器回复时,Windows 返回 WSAECONNRESET(这意味着端口已关闭 - http://support.microsoft.com/kb/263823

如何从服务器正确应答客户端(即使用 sendto 发送时强制客户端绑定端口?)

编辑:添加一些源代码:

bool InitClient()
{
    internal->sock = socket(PF_INET, SOCK_DGRAM, 0);
    char8 yes = 1;
    setsockopt(internal->sock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int32));
    return internal->sock != -1;
}
void Send(const IpAddress & target, const uint16 port, const char8 * data, int32 size )
{
    sockaddr_in trgt;
    memset(&trgt, 0, sizeof(trgt));
    trgt.sin_family = AF_INET;
    trgt.sin_port = htons(port);
    trgt.sin_addr.s_addr = target.GetRaw();

    if(sendto(internal->sock, (const char8 *)data, size, 0, (PSOCKADDR)&trgt, sizeof(trgt)) == SOCKET_ERROR)
    {
        LOG("Network sending error: %d", WSAGetLastError());
    }
}

【问题讨论】:

标签: sockets udp sendto


【解决方案1】:

调用“绑定”函数来指定要发送的本地端口。下面是使用端口 4567 的示例。确保检查 bind 的返回值。创建套接字后调用此代码。

sockaddr_in local = {};
local.family = AF_INET;
local.port = htons(4567);
local.addr = INADDR_ANY;

bind(internal->sock,(sockaddr*)&local, sizeof(local));

如果您绑定到端口 0 而不是 4567,那么操作系统将为您选择一个随机端口并将其用于所有后续发送和接收。你可以调用getsockname来发现调用bind后操作系统为你选择了哪个端口。

【讨论】:

  • 如果您绑定到端口 0 而不是 4567,那么操作系统将为您选择一个随机端口并将其用于所有后续发送和接收。你可以调用getsockname来发现调用bind后操作系统为你选择了哪个端口。
  • 哈,这么简单:recvfrom 之后我没有 ntohs 源端口。您对显式端口绑定的建议给了我线索
猜你喜欢
  • 2011-05-04
  • 1970-01-01
  • 2018-12-08
  • 2015-10-21
  • 1970-01-01
  • 2018-09-05
  • 2012-09-21
  • 2020-03-27
相关资源
最近更新 更多