1
votes

I have simple server and client in UDP (WinSocks/C++).

I send datagram client -> server via sendto, and reply from server to client using the ip and port obtained from recvfrom function.

I found out that:

  1. Every sendto from client is being sent from different port
  2. When trying to reply from server Windows returns WSAECONNRESET (which mean that port is closed - http://support.microsoft.com/kb/263823)

How can I properly answer client from server (ie force port binding on client when sending using sendto?)

Edit: Adding some source code:

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
See if this answer helps you out any?sarnold
msdn.microsoft.com/en-us/library/windows/desktop/… <- "Note: If a socket is opened, a setsockopt call is made, and then a sendto call is made, Windows Sockets performs an implicit bind function call." And this: cboard.cprogramming.com/networking-device-communication/…PiotrK
If there had been an implicit bind call made, then I would expect each new use of sendto to re-use the previous port...sarnold

1 Answers

4
votes

Call the "bind" function to specify a local port to send from. Example of using port 4567 below. Make sure to check the return value from bind.Call this code after you create the socket.

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

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

If you bind to port zero instead of 4567 then the os will pick a random port for you and use it for all subsequent send and receives. You can call getsockname to discover which port the os picked for you after calling bind.