title: C Windows winapi + multi-threading (HANDLE)_beginthreadex fail
body: <p>This code ruined all my day. Basically I have a list of 50 webservers I administrate, I want to check them if up/alive (isAlive() function), I parse my webservers.txt file with the 50 ips/hostnames and for fastness I try to use threads (10, 20 or 30 doesn't matter) then my compiled code seems only to exit without doing anything...any idea/help?</p>
  
  <pre><code>#include &lt;windows.h&gt;
  #include &lt;stdio.h&gt;
  #include &lt;string.h&gt;
  #include &lt;winsock.h&gt;
  #include &lt;process.h&gt;
  #include &lt;string.h&gt;
  
  #pragma comment(lib, "wsock32.lib")
  
  unsigned int _stdcall isAlive(void *ptr)
  {
    struct sockaddr_in blah;
    struct hostent *he;
    WSADATA wsaData;
    int i;
    WORD wVersionRequested;
    SOCKET sock;
    char* addr = (char*)ptr;
  
    char buff[1024];
    char *ex;
    ex="GET /alive.php HTTP/1.0\n\n";
    char *fmsg="ALIVE";
  
    wVersionRequested = MAKEWORD(1, 1);
    if (WSAStartup(wVersionRequested , &amp;wsaData)){
      printf("Winsock Initialization failed.\n");
      return(1);
    }
  
    if ((sock=socket(AF_INET,SOCK_STREAM,0))==INVALID_SOCKET){
      printf("Can not create socket.\n");
      return(1);
    }
    sock = socket(AF_INET,SOCK_STREAM,0);
    blah.sin_family = AF_INET;
    blah.sin_port = htons(80);
    blah.sin_addr.s_addr = inet_addr(addr);
  
    if ((he=gethostbyname(addr))!=NULL){
      memcpy((char *)&amp;blah.sin_addr.s_addr,he-&gt;h_addr,he-&gt;h_length);
    }
    else{
      if((blah.sin_addr.s_addr=inet_addr(addr))==-1){
        WSACleanup();
        return(1);
      }
    }
  
    if (connect(sock,(struct sockaddr*)&amp;blah,sizeof(blah))==0){
      send(sock,ex,strlen(ex),0);
      recv(sock,buff,sizeof(buff),0);
      if(strstr(buff,fmsg)!=NULL){
        printf("ALIVE: %s", addr);
      }
    }
  
    closesocket(sock);
    WSACleanup();
    _endthreadex(0);
    return(1);
  }
  
  int main(int argc,char *argv[])
  {
    if(argc!=2){
      printf("Usage: %s &lt;webservers list&gt;\n", argv[0]);
      return(1);
    }
  
    char *inname = argv[1];
    FILE *infile;
    char line_buffer[BUFSIZ];
    char line_number;
  
    infile = fopen(inname, "r");
    if (!infile) {
      printf("Couldn't open file %s for reading.\n", inname);
      return 0;
    }
  
    line_number = 0;
    HANDLE hThreadArray[200];
    while (fgets(line_buffer, sizeof(line_buffer), infile)) {
      ++line_number;
      unsigned threadID;
      hThreadArray[line_number] = (HANDLE)_beginthreadex(0, 0, isAlive, line_buffer, 0, &amp;threadID);
    }
    WaitForMultipleObjects(sizeof(line_buffer), hThreadArray, TRUE, INFINITE);
    return 0;
  }
  </code></pre>
  
  <p>New code after your advices:</p>
  
  <pre><code>#include &lt;windows.h&gt;
  #include &lt;stdio.h&gt;
  #include &lt;string.h&gt;
  #include &lt;winsock.h&gt;
  #include &lt;process.h&gt;
  #include &lt;string.h&gt;
  
  #pragma comment(lib, "wsock32.lib")
  
  unsigned int _stdcall isAlive(void *ptr)
  {
    struct sockaddr_in blah;
    struct hostent *he;
    WSADATA wsaData;
    int i;
    WORD wVersionRequested;
    SOCKET sock;
    char* addr = (char*)ptr;
  
    char buff[1024];
    char *ex;
    ex="GET /alive.php HTTP/1.1\n\n";
    char *fmsg="ALIVE";
  
    wVersionRequested = MAKEWORD(1, 1);
    if (WSAStartup(wVersionRequested , &amp;wsaData)){
      printf("Winsock Initialization failed.\n");
      return(1);
    }
  
    if ((sock=socket(AF_INET,SOCK_STREAM,0))==INVALID_SOCKET){
      printf("Can not create socket.\n");
      return(1);
    }
    sock = socket(AF_INET,SOCK_STREAM,0);
    blah.sin_family = AF_INET;
    blah.sin_port = htons(80);
    blah.sin_addr.s_addr = inet_addr(addr);
  
    if ((he=gethostbyname(addr))!=NULL){
      memcpy((char *)&amp;blah.sin_addr.s_addr,he-&gt;h_addr,he-&gt;h_length);
    }
    else{
      if((blah.sin_addr.s_addr=inet_addr(addr))==-1){
        WSACleanup();
        return(1);
      }
    }
  
    if (connect(sock,(struct sockaddr*)&amp;blah,sizeof(blah))==0){
      send(sock,ex,strlen(ex),0);
      recv(sock,buff,sizeof(buff),0);
      if(strstr(buff,fmsg)!=NULL){
        printf("ALIVE: %s\n", addr);
      }
    }
  
    closesocket(sock);
    WSACleanup();
    _endthreadex(0);
    return(1);
  }
  
  int main(int argc,char *argv[])
  {
    if(argc!=2){
      printf("Usage: %s &lt;webservers list&gt;\n", argv[0]);
      return(1);
    }
  
    char *inname = argv[1];
    FILE *infile;
    char line_buffer[10000];
    char line_number;
  
    infile = fopen(inname, "r");
    if (!infile) {
      printf("Couldn't open file %s for reading.\n", inname);
      return 0;
    }
  
    line_number = 0;
    HANDLE hThreadArray[200];
    while (fgets(line_buffer, sizeof(line_buffer), infile)) {
      unsigned threadID;
      hThreadArray[line_number] = (HANDLE)_beginthreadex(0, 0, isAlive, line_buffer, 0, &amp;threadID);
      ++line_number;
    }
    WaitForMultipleObjects(line_number, hThreadArray, TRUE, INFINITE);
    fclose(infile);
    return 0;
  }
  </code></pre>
  
  <p>Now my code runs but it takes the last line in my text and makes multiple threads with that, I'm lost :(</p>
  
  <p>hosts.txt (11 lines in it)</p>
  
  <pre><code>myhost.com
  mysecondhost.com
  ...
  mylasthost.com
  </code></pre>
  
  <p>result:
  C:\Documents and Settings\Xtmtrx\Desktop\Code>checkalive.exe hosts.txt</p>
  
  <pre><code>ALIVE: mylasthost.com
  ALIVE: mylasthost.com
  ALIVE: mylasthost.com
  ALIVE: mylasthost.com
  ALIVE: mylasthost.com
  ALIVE: mylasthost.com
  ALIVE: mylasthost.com
  ALIVE: mylasthost.com
  ALIVE: mylasthost.com
  ALIVE: mylasthost.com
  ALIVE: mylasthost.com
  </code></pre>
  
  <p>If I do this:</p>
  
  <pre><code>#define MAX 10000
  
  /* snip */
  
  HANDLE hThreadArray[200];
  char str[MAX];
  char *x[MAX];
  int i =0;
  
  while(!feof(infile)) {
    while(fgets(str, sizeof str, infile)) {
      unsigned threadID;
      x[i] = strdup(str);
      printf("%s", *(x+i));
      hThreadArray[i] = (HANDLE)_beginthreadex(0, 0, isAlive, *(x+i), 0, &amp;threadID);
      i++;
    }
  }
  </code></pre>
  
  <p>would be right?</p>
  
  <p>LAST EDIT:</p>
  
  <p>This is my finished code, seems to work, I added timeout also but doesn't seem to be taken in consideration so it can hang on some hosts:</p>
  
  <pre><code>#include &lt;windows.h&gt;
  #include &lt;stdio.h&gt;
  #include &lt;string.h&gt;
  #include &lt;winsock.h&gt;
  #include &lt;process.h&gt;
  #include &lt;string.h&gt;
  
  #pragma comment(lib, "wsock32.lib")
  
  #define MAX 10000
  
  unsigned int _stdcall isAlive(void *ptr)
  {
    struct sockaddr_in blah;
    struct hostent *he;
    WSADATA wsaData;
    int i;
    WORD wVersionRequested;
    SOCKET sock;
    char* addr = (char*)ptr;
  
    char buff[1024];
    char *request;
    request="GET /alive.php HTTP/1.0\n\n";
    char *fmsg="ALIVE";
  
    wVersionRequested = MAKEWORD(1, 1);
    if (WSAStartup(wVersionRequested , &amp;wsaData)){
      printf("Winsock Initialization failed.\n");
      return(1);
    }
  
    if ((sock=socket(AF_INET,SOCK_STREAM,0))==INVALID_SOCKET){
      printf("Can not create socket.\n");
      return(1);
    }
    sock = socket(AF_INET,SOCK_STREAM,0);
    blah.sin_family = AF_INET;
    blah.sin_port = htons(80);
    blah.sin_addr.s_addr = inet_addr(addr);
  
    if ((he=gethostbyname(addr))!=NULL){
      memcpy((char *)&amp;blah.sin_addr.s_addr,he-&gt;h_addr,he-&gt;h_length);
    }
    else{
      if((blah.sin_addr.s_addr=inet_addr(addr))==-1){
        WSACleanup();
        return(1);
      }
    }
  
    if (connect(sock,(struct sockaddr*)&amp;blah,sizeof(blah))==0){
      send(sock,request,strlen(request),0);
      recv(sock,buff,sizeof(buff),0);
      if(strstr(buff,fmsg)!=NULL){
        printf("ALIVE: %s", addr);
      }
    }
  
    closesocket(sock);
    WSACleanup();
    _endthreadex(0);
    return(1);
  }
  
  int main(int argc,char *argv[])
  {
    if(argc!=2){
      printf("Usage: %s &lt;webservers list&gt;\n", argv[0]);
      return(1);
    }
  
    char *inname = argv[1];
    FILE *infile;
    char line_buffer[BUFSIZ];
    char line_number;
  
    infile = fopen(inname, "r");
    if (!infile) {
      printf("Couldn't open file %s for reading.\n", inname);
      return 0;
    }
  
    HANDLE hThreadArray[200];
    char str[MAX];
    char *x[MAX];
    int i = 0;
    while(!feof(infile)) {
      while(fgets(str, sizeof str, infile)) {
        unsigned threadID;
        x[i] = strdup(str);
        //printf("%s", *(x+i)); // DEBUG
        hThreadArray[i] = (HANDLE)_beginthreadex(0, 0, isAlive, *(x+i), 0, &amp;threadID);
        i++;
        }
    }
  
    WaitForMultipleObjects(i, hThreadArray, TRUE, INFINITE);
    fclose(infile);
    return 0;
  }
  </code></pre>
  
  <p>Any thoughts/ideas?</p>