1

我有一个丑陋的 C 代码(我是 Windows 下的 C 新手)不要评判我......我让它成为多线程,它从我的网络服务器列表中读取并检查它们是否还活着,我需要快速它是多线程的。搜索了很多谷歌和howtos,我能做的最好的如下:

#include <windows.h>
#include <stdio.h>
#include <string.h>
#include <winsock.h>
#include <process.h>
#include <string.h>

#pragma comment(lib, "wsock32.lib")

int isAlive(char *addr)
{
  struct sockaddr_in blah;
  struct hostent *he;
  WSADATA wsaData;
  int i;
  WORD wVersionRequested;
  SOCKET sock;

  char buff[1024];
  char *ex;
  ex="GET /alive.php HTTP/1.0\n\n";
  char *fmsg="ALIVE";  

  wVersionRequested = MAKEWORD(1, 1);
  if (WSAStartup(wVersionRequested , &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 *)&blah.sin_addr.s_addr,he->h_addr,he->h_length);
  }
  else{
    if((blah.sin_addr.s_addr=inet_addr(addr))==-1){
      WSACleanup();
      return(1);
    }
  }

  if (connect(sock,(struct sockaddr*)&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: scan <webservers list>\n");
    return(1);
  }

  char *inname = argv[1];
  FILE *infile;
  char line_buffer[BUFSIZ];
  char line_number;
  int numconnect;

  infile = fopen(inname, "r");
  if (!infile) {
    printf("Couldn't open file %s for reading.\n", inname);
    return 0;
  }

  line_number = 0;
  numconnect=20;
  while (fgets(line_buffer, sizeof(line_buffer), infile)) {
    ++line_number;
    //printf("%s", line_buffer);
    unsigned x;
    unsigned tempThreadID;
    for(x=0;x<numconnect;++x){
        _beginthreadex(0, 0, isAlive, line_buffer, 0, &tempThreadID);
    }
  }
  return 0;
}

当我尝试在 VC 10 下编译时,出现以下错误:

checkalive.c(90):错误 C2664:“ beginthreadex”:无法将参数 3 从“int ( _cdecl *)(char *)”转换为“unsigned int (__stdcall *)(void *)”

感谢帮助!

4

1 回答 1

1

请参阅 MSDN 文档了解beginthreadex。您需要将签名更改isAlive

unsigned int _stdcall isAlive(void *ptr)

_stdcall指定不同的调用约定。有关可用选项的列表,请参见此处

您可以简单地通过强制转换来检索您的addr论点ptr

char* addr = (char*)ptr;
于 2013-01-27T12:57:42.537 回答