title: C++ WinSock2: WSA_INVALID_HANDLE on connect() call
body: <p>Good day!</p>
  
  <p>I'm a somewhat experienced programmer in higher level languages, but this is my first time diving into socket code on lower level languages, so please bear with me.</p>
  
  <p>I seem to be getting an error upon the <code>connect()</code> call.  In my main function, <code>WSAGetLastError()</code> prints that this is error number 6 which according to MSDN is <code>WSA_INVALID_HANDLE</code>.  This seems strange as there is no detailing of that particular error code on the <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms737625%28v=vs.85%29.aspx" rel="nofollow" title="MSDN page for the `connect&#40;&#41;`">MSDN page for the <code>connect()</code> function</a> (unless I'm going blind), and my google searches are all inconclusive</p>
  
  <p>I'm using a custom socket_t structure as my code is designed to (eventually) be cross platform.  The <code>socket_connect()</code> function is called from the main code page.</p>
  
  <p><code>socket_t</code> definition:</p>
  
  <pre><code>typedef struct
  {
      //windows-specific
      SOCKADDR_IN *addr_in;
      u_long mode;
      SOCKET socket;//acutal SOCKET structure
  
      // General
      bool listening;//set to true if actively listening
      bool thread_terminate;//when boolean is set to true, listening thread terminates
      void (*error_callback) (int);
      http_response_t * response;
  } socket_t;
  </code></pre>
  
  <p><code>socket_connect()</code> function:</p>
  
  <pre><code>//see socket_t definition in socket.h
  //returns 0 on success, SOCKET_ERROR on WinSock failure, positive error code on ANSI DNS failure
  int socket_connect(socket_t * sock, char * addr, int port)
  {
      //bear in mind sock is the custom socket_t structure.  sock-&gt;socket is the actual SOCKET structure.
      //pardon the nomenclature.  rookie code.
  
      //DNS lookup structures
      struct addrinfo     * res           = NULL;// Result of the getaddrinfo() call
      struct sockaddr_in  * sockaddr_v4   = NULL;// IPv4 sockaddr structure
  
      // So-called "hints" structure detailed in the getaddrinfo() MSDN page.
      // I guess it contains information for the DNS lookup.
      struct addrinfo hints;
      memset(&amp;hints, 0, sizeof(hints));
      hints.ai_family     = AF_UNSPEC;
      hints.ai_socktype   = SOCK_STREAM;
      hints.ai_protocol   = IPPROTO_TCP;
  
      //Perform DNS lookup
      DWORD getaddrinfo_res = getaddrinfo(addr, "80\0", &amp;hints, &amp;res);//hard-code Port number for now...
      if(getaddrinfo_res != 0) return getaddrinfo_res;//positive DNS error code
  
              //debug information
      std::cout &lt;&lt; "DNS lookup responses:" &lt;&lt; std::endl;
      //for each
      int i = 0;//counter
      for(struct addrinfo * ptr = res; ptr != NULL; ptr = ptr-&gt;ai_next)
      {
          std::cout &lt;&lt; "Response number " &lt;&lt; i + 1 &lt;&lt; std::endl;
          std::cout &lt;&lt; "Flags: " &lt;&lt; ptr-&gt;ai_flags &lt;&lt; std::endl;
  
          std::cout &lt;&lt; "Family: ";
          switch(ptr-&gt;ai_family)
          {
          case AF_INET:
              sockaddr_v4 = (struct sockaddr_in *) ptr-&gt;ai_addr;//set current address
              sock-&gt;addr_in = sockaddr_v4;//set socket address
  
              std::cout &lt;&lt; "AF_INET (IPv4)" &lt;&lt; std::endl;
              std::cout &lt;&lt; "Addr: " &lt;&lt; inet_ntoa(sockaddr_v4-&gt;sin_addr) &lt;&lt; std::endl;
              break;
          case AF_UNSPEC:
              std::cout &lt;&lt; "UNSPECIFIED" &lt;&lt; std::endl;
              break;
          default:
              std::cout &lt;&lt; "UNKNOWN\t(" &lt;&lt; ptr-&gt;ai_family &lt;&lt; ")" &lt;&lt; std::endl;
              break;
          }
  
          i++;
      }
  
      //initialize actual SOCKET
      sock-&gt;socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);// TCP/IP, stream-oriented, and TCP rather than UDP; respectively
      if(sock-&gt;socket == INVALID_SOCKET) return SOCKET_ERROR;
  
      //actual connection
      std::cout &lt;&lt; WSAGetLastError() &lt;&lt; std::endl;
      int connect_res = connect(sock-&gt;socket, (SOCKADDR *) sockaddr_v4, sizeof(sockaddr_v4));///have to convert SOCKADDR_IN to a SOCKADDR pointer here.  Not sure why.
      if(connect_res == SOCKET_ERROR) return SOCKET_ERROR;
  
      //make nonblocking
      /*
      sock-&gt;mode = 1;
      int ioctl = ioctlsocket(sock-&gt;socket, FIONBIO, &amp;(sock-&gt;mode));//I/O Control Socket.  Not sure what FIONBIO means.  pointer to sock-&gt;mode = 1 ensures nonblockingness.
      if(ioctl == SOCKET_ERROR) return SOCKET_ERROR;
      */// (include this?)
  
      return 0;
  }
  </code></pre>
  
  <p><code>socket_connect()</code> function call:</p>
  
  <pre><code>int connect_res = conley::socket_connect(sock, "www.google.com", 80);
  if(connect_res &gt; 0) std::cout &lt;&lt; "DNS ERR " &lt;&lt; connect_res &lt;&lt; std::endl &lt;&lt; std::endl;
  if(connect_res &lt; 0) std::cout &lt;&lt; "CONNECT ERR " &lt;&lt; WSAGetLastError() &lt;&lt; std::endl &lt;&lt; std::endl;
  if(connect_res == 0) std::cout &lt;&lt; "Connected" &lt;&lt; std::endl &lt;&lt; std::endl;
  </code></pre>
  
  <p>Thank you for your time!
  - Jake</p>