2

I have a client application that sends TCP packets. Currently, my application does this: creates a socket, binds and sends the packets.

struct sockaddr_in localaddress;
localaddress.sin_port = htons(0);
localaddress.sin_addr.s_addr = INADDR_ANY;

int socket;
socket = socket(AF_INET, SOCK_STREAM, 0));
bind(socket, (struct sockaddr *)&sin,sizeof(struct sockaddr_in) );

And in another thread, the application connects and sends the packets:

struct socketaddr_in remoteaddress;
// omitted: code to set the remote address/ port etc...
nRet = connect (socket, (struct sockaddr * ) & remoteaddress, sizeof (sockaddr_in ));
if (nRet == -1)
    nRet = WSAGetLastError();
if (nRet == WSAEWOULDBLOCK) {
    int errorCode = 0;
    socklen_t codeLen = sizeof(int);
    int retVal = getsockopt(
            socket, SOL_SOCKET, SO_ERROR, ( char * ) &errorCode, &codeLen );
    if (errorCode == 0 && retVal != 0)
        errorCode = errno;
}
/* if the connect succeeds, program calls a callback function to notify the socket is connected, which then calls send() */

Now I want to specify a port range for local port, so I changed the code to

nPortNumber = nPortLow;
localaddress.sin_port = htons(nPortNumber);

and loops nPortNumber in my port range, e.g ( 4000 - 5000 ) until the bind succeeds.

Since I always start my nPortNumber from the low port, if a socket is previously created on the same port, I get the WSAEADDRINUSE error as errorCode, which is too late for me because it has already passed the socket creation stage. (Why didn't I get WSAEADDRINUSE at bind() or connect()?)

Is there a way I can get the WSAEADDRINUSE earlier or is there a way to create a socket in the port range that binds and connects?

Thanks in advance!

user775614
  • 237
  • 3
  • 7
  • Your application needs you to control the source port? Also, are you actually setting the remote address to connect to and you just omitted that from your code for brevity? – evil otto Jul 22 '11 at 05:20
  • @evil-otto , My application needs to control the source port to be in the port range. Yes, I'm setting the remote address. – user775614 Jul 22 '11 at 12:19

1 Answers1

0

I cannot answer with 100% certainty as for that I should know at which point you actually get WSAEADDRINUSE.

IN any case, it is normal you don't get it at bind, because you use INADDR_ANY. IIRC, this actually delays the bind process to the actual connect (my guess is it then changes the INADDR based on routing for the remote addr). However, as far as I know, you should then actually get the error at the call of connect...

KillianDS
  • 16,936
  • 4
  • 61
  • 70