使用sendto发送时如何强制UDP中的客户端打开端口

时间:2011-12-15 22:17:07

标签: sockets udp sendto

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

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

我发现了:

  1. 来自客户端的每个sendto都是从不同的端口发送的
  2. 尝试从服务器回复时Windows返回WSAECONNRESET(表示该端口已关闭 - http://support.microsoft.com/kb/263823
  3. 如何从服务器正确回答客户端(即使用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());
        }
    }
    

1 个答案:

答案 0 :(得分:4)

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

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

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

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