1

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());
    }
}
PiotrK
  • 4,210
  • 6
  • 45
  • 65
  • See if [this answer](http://stackoverflow.com/a/4487043/377270) helps you out any? – sarnold Dec 15 '11 at 22:25
  • http://msdn.microsoft.com/en-us/library/windows/desktop/ms740148%28v=vs.85%29.aspx <- "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: http://cboard.cprogramming.com/networking-device-communication/71964-udp-client-needs-bind.html – PiotrK Dec 15 '11 at 22:33
  • 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 Dec 15 '11 at 22:43

1 Answers1

4

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.

selbie
  • 100,020
  • 15
  • 103
  • 173
  • If you bing 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. – selbie Dec 15 '11 at 22:44
  • Hah, so simple: I didn't ntohs source port after recvfrom. Your suggestion with explict port binding gave me the clue – PiotrK Dec 15 '11 at 22:59