title: How to Use Client Socket Bind
body: <p>I'm writing a Socket library and I'm having some trouble with client sockets that bind to a specific address and port. I'm currently testing my winsock TCP library, although I'm sure there's no reason why I wouldn't have the same problems on *nix. So far everything works fine (if I <code>connect()</code> without calling <code>bind()</code> first I can <code>send()</code> and <code>recv()</code>).</p>
  
  <p>I have a server listening on 192.168.1.99:XXXX (my machine's address). </p>
  
  <p>I then get a socket and bind to 192.168.1.99:0. I get a socket error 10049 (<code>WSAEADDRNOTAVAIL</code>) when I try to connect. The same thing happens if I try to bind to 0.0.0.0:0.</p>
  
  <p>If I try to bind to 127.0.0.1:0 or localhost or leave the hostname NULL (if this is even possible, should I be using the AI_PASSIVE flag?) and then connect I get a 10061 (<code>WSACONNREFUSED</code>).</p>
  
  <p>Anyone know the right way to do this here?</p>
  
  <p><strong>EDIT3:</strong> Turns out the issue was that I was calling socket before I called bind and then calling it again before I called connect. I switched it to only call socket before calling bind. I don't know if anyone else is confused by this whole concept, so I'll leave this here unless someone feels it should be closed?</p>
  
  <p><strong>EDIT 2:</strong> Is the issue that I call socket twice?</p>
  
  <p><strong>EDIT:</strong> Here's some of the functionality</p>
  
  <pre><code>int main() {
      WSADATA wsaData;   // if this doesn't work
  
      if(WSAStartup(MAKEWORD(2,0), &amp;wsaData) != 0) {
          cout &lt;&lt; WSAStartup failed &lt;&lt; endl;
          return -1;
      }
  
      ClientSocket* cs = new ClientSocket("192.168.1.99", "XXXX");
  
      cs-&gt;bind("", "0"); //error 10049 (WSAEADDRNOTAVAIL)
      //cs-&gt;bind("", "60000"); //error 10049 (WSAEADDRNOTAVAIL)
  
      //cs-&gt;bind("0.0.0.0", "0"); //error 10049 (WSAEADDRNOTAVAIL)
      //cs-&gt;bind("0.0.0.0", "60000"); //error 10049 (WSAEADDRNOTAVAIL)
  
      //cs-&gt;bind("192.168.1.99", "0"); //error 10061 (WSACONNREFUSED)
      //cs-&gt;bind("192.168.1.99", "60000"); //error 10061 (WSACONNREFUSED)
  
      //cs-&gt;bind("127.0.0.1", "0"); //error 10061 (WSACONNREFUSED)
      //cs-&gt;bind("127.0.0.1", "60000"); //error 10061 (WSACONNREFUSED)
  
      //cs-&gt;bind("localhost", "0"); //error 10061 (WSACONNREFUSED)
      //cs-&gt;bind("localhost", "60000"); //error 10061 (WSACONNREFUSED)
  
  
      cs-&gt;connect(); //connects to the info passed in ctor
  
      Socket* s = cs-&gt;getSocket();
  
      if(s == NULL) {
          cs-&gt;close();
          return -1;
      }
  
      .
      .
      .
      .
  }
  
  //these are the methods exposed by my API
  int ClientSocket::bind(std::string hostname, std::string port) {
      if(bound) {
          return -1;
      }
      if(connected) {
          return -2;
      }
  
      //this defines what specialSockOp will do
      ssop = &amp;ClientSocket::BaseDef::bind;
  
      info-&gt;hostname = hostname;
      if(hostname.compare("") == 0) {
          info-&gt;AI_FLAG_PASSIVE = true;
      }
      info-&gt;port = port;
  
      //calls SpecialSocket::socket()
      socket();
  
      bound = true;
  
      return 0;
  }
  
  int ClientSocket::connect() {
      if(connected) {
          return SOCKET_ERROR;
          //throw exception
      }
      if(bound) {
          ssop = &amp;ClientSocket::BaseDef::connect;
      }
      socket();
      return 0;
  }
  
  void SpecialSocket::WinImp::socket() {
      struct addrinfo *results = NULL, *p = NULL, hints;
      int rv;
  
      ZeroMemory(&amp;hints, sizeof(hints));
      hints.ai_family = (containerClass-&gt;info-&gt;ipType == IP_DUAL ? AF_UNSPEC :
          containerClass-&gt;info-&gt;ipType == IPV6 ? AF_INET6 : AF_INET);
      hints.ai_socktype = (containerClass-&gt;info-&gt;protocol == TCP ? SOCK_STREAM : 
          SOCK_DGRAM);
      hints.ai_protocol = 0;
      if(containerClass-&gt;info-&gt;AI_FLAG_PASSIVE) {
          hints.ai_flags |= AI_PASSIVE;
      }
      if(containerClass-&gt;info-&gt;AI_FLAG_CANONNAME) {
          hints.ai_flags |= AI_CANONNAME;
      }
  
      //cStringHostname returns NULL if an empty string has been passed in
      if((rv = getaddrinfo(containerClass-&gt;info-&gt;cStringHostname(),
           containerClass-&gt;info-&gt;cStringPort(), &amp;hints, &amp;results)) != 0) {
              //throw exception
      }
  
      for(p = results; p != NULL; p = p-&gt;ai_next) {
          if((containerClass-&gt;info-&gt;sock_fd = ::socket(p-&gt;ai_family,
                   p-&gt;ai_socktype, p-&gt;ai_protocol)) == INVALID_SOCKET) {
              closesocket(containerClass-&gt;info-&gt;sock_fd);
              continue;
          }
  
          //for a ClientSocket specialSockOp will call either bind or connect
          //corresponding to the function called by ClientSocket
          if(containerClass-&gt;specialSockOp(p-&gt;ai_addr) == SOCKET_ERROR) {
              closesocket(containerClass-&gt;info-&gt;sock_fd);
              continue;
          }
  
          break; //successfully connected
      }
  
      if(p == NULL) {
          //none of the connections in results were good
          //throw exception - could not connect
      }
  
      freeaddrinfo(results);
  }
  
  int SpecialSocket::WinImp::bind(const void* addr) {
      struct sockaddr* ai_addr = (struct sockaddr*)addr;
  
      return ::bind(containerClass-&gt;getSockFd(), ai_addr, sizeof(*ai_addr));
  
  }
  
  int ClientSocket::WinImp::connect(const void* addr) {
      struct sockaddr* ai_addr = (struct sockaddr*)addr;
  
      int result = ::connect(containerClass-&gt;getSockFd(), ai_addr, sizeof(*ai_addr));
  
      if(result == SOCKET_ERROR) {
          //these are where my errors are showing up
          cout &lt;&lt; "error after connect() is - " &lt;&lt; WSAGetLastError() &lt;&lt; endl;
          return SOCKET_ERROR;
      }
  
      containerClass-&gt;servInfo-&gt;sock_fd = containerClass-&gt;getSockFd();
  
      //I separated the functionality here - Socket can only send/recv
      containerClass-&gt;s = new Socket();
      //I use getpeername here to get information about the remote socket
  
      //Long story but basically sets up the Socket
      containerClass-&gt;initRWSocket(containerClass-&gt;s, containerClass-&gt;servInfo);
  
      return result;
  }
  </code></pre>
  
  <p>A user can then call <code>ClientSocket.getSocket()</code> which returns a <code>Socket</code> that they are then able to <code>send/recv</code> on. In my case, this is returning <code>NULL</code> since the <code>Socket</code> is never instantiated, because <code>SpecialSocket::connect</code> returns before it does that.</p>