#include <winsock2.h>
#include <windows.h>
#include <stdio.h>

#pragma comment(lib,"ws2_32.lib")


unsigned long inet_aton(const char *host) {
  struct hostent *he;
  unsigned long ip = inet_addr(host);

  if (ip == INADDR_NONE) {
    he = ::gethostbyname(host);
    if (he)
      ip = *(unsigned long *)(he->h_addr_list[0]);
  }

  return ip;
}


int main( int argc, char *argv[]) {
  WSAData _wsa_data;
  int r = ::WSAStartup( MAKEWORD(2,0), &_wsa_data );
    if (r) {
      puts("startup error");
      return 0;
    }

  SOCKET sock = ::socket( AF_INET, SOCK_STREAM, 0 );

  struct sockaddr_in addr = {0};
  addr.sin_port = htons(80);
  addr.sin_family = AF_INET;
  addr.sin_addr.s_addr = inet_aton(argc>1 ? argv[1] : "localhost");
    if (addr.sin_addr.s_addr == INADDR_NONE ) {
      puts("no host addr");
      closesocket(sock);
      WSACleanup();
      return 0;
    }

  // ソケットを非同期モードにする
  u_long arg = (u_long)TRUE;
  r = ::ioctlsocket(sock, FIONBIO, &arg);
    if ( r == SOCKET_ERROR ) {
      puts("ioctlsocket error");
      closesocket(sock);
      WSACleanup();
      return 0;
    }

  // コネクト開始
  r = ::connect(sock, (struct sockaddr *)&addr, sizeof(sockaddr_in));

  if (r >= 0) {
    // いきなり connect に成功した .. これはこれで。。いいや。。
    puts("connect ok!");
  }
  else {
    DWORD e = ::GetLastError();

    // connect 待ちが始まった？
    if ( e == WSAEWOULDBLOCK ) {
      puts("in progress..");

      // 待っている間，2 秒毎に <.> を表示する
      DWORD start, now;
      start = now = ::GetTickCount();
      struct timeval tv;
      tv.tv_sec = 0;
      tv.tv_usec = 100;
      fd_set fds;
      do {
        FD_ZERO(&fds);
        FD_SET(sock,&fds);
        r = ::select(sock+1,NULL,&fds,NULL,&tv);
        if (now + 2000 <= ::GetTickCount() ) {
          printf(".");
          now = ::GetTickCount();
        }
      }while (r == 0);

      int arglen = sizeof(int);
      if (::getsockopt(sock,SOL_SOCKET,SO_ERROR,(char *)&r,&arglen) < 0)
        r = ::GetLastError();

      if (r) printf("\nconnect failed - error %d\n",r);
      else {
        printf("\nconnect successful\n");
        printf("time to connect - %d\n", ::GetTickCount() - start);
      }

    }else{
      printf("error %d\n", e);
    }
  }

  closesocket(sock);

  WSACleanup();
  return 0;
}

