1
votes

Both the IP address and Port are confirmed not used by netstat -a -n. When I use gdb and break in the method calling bind I see that the correct IP address and Port are being used along with a reasonable socket address length of 16. This is for a UDP Listener. The remote IP is static and read from a configuration file.

This is the code,

void CSocket::Bind(IpEndPoint& endPoint)
{
    int bindResult = bind( socketHandle, endPoint.GetSockAddrPtr(), 
        endPoint.GetAddrLength());
    if(bindResult < 0)
    {
        TRACE_ERROR("Failed to bind to socket. %s. IpAddress %s Port %d AddrLength %d",
            strerror(errno), endPoint.GetIpAddressString(), 
            ntohs(endPoint.GetPort()), endPoint.GetAddrLength());

this is from gdb,

Breakpoint 1, CSocket::Bind (this=0x819fa24, ipAddress="192.0.2.77", port=4185) at Socket.cpp:126

and this is the TRACE_ERROR from the code above

ERROR: Failed to bind to socket. errno 99 (Cannot assign requested address). IpAddress 192.0.2.77 Port 4185 AddrLength 16

I've been re-reading Beej's Guide to Network Programming but not finding a clue. This is UDP so a connection should not be required to bind. The firewall is off. Where else should I be looking?

1
I'd look at how the ip address as string is converted to the required struct sockaddr object. Is the address you want to bind to really a local one? If it shall be the remote host, use connect instead. Is the port already in use? (...)Aconcagua
Just a tip: I personally prefer the error code rather than the error string - and I'm probably not the only one... Might be a good idea to use e. g. "%d (%s)", errno, strerror(errno) to satisfy both fractions.Aconcagua
@Aconcagua thanks. Added error code as you suggested. Why does UDP need connect if it is connectionless?jacknad
Following on what @Aconcagua said: You want to bind an address that is local (not one that's "not in use"). You can't just make up a local address. You either use INADDR_ANY to bind to any address, or you need to bind one that is assigned to one of your local interfaces. This is likely the problem. (bind sets the local address, connect sets the remote address -- or, with UDP, you can specify the remote address per packet with sendto.)Gil Hamilton
@GilHamilton Adding the interface in /etc/network/interfaces and another Network Adapter in settings seemed to allow the Listener to bind without complaint. I suppose I need to learn a little more about how local interfaces work. If you move your comment to the answer section I'll accept it. Thank you very much.jacknad

1 Answers

1
votes

Following on what @Aconcagua said: You want to bind an address that is local (not one that's "not in use"). You can't just make up a local address. You either use INADDR_ANY to bind to any address, or you need to bind one that is assigned to one of your local interfaces. This is likely the problem. (bind sets the local address, connect sets the remote address -- or, with UDP, you can specify the remote address per packet with sendto.) – Gil Hamilton