⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ping.c

📁 prozgui是一款Linxu下著名的下载工具
💻 C
字号:
/****************************************************************************** libprozilla - a download accelerator library Copyright (C) 2001 Kalum Somaratna This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA******************************************************************************/#include "common.h"#include "prozilla.h"#include "connect.h"#include "misc.h"#include "url.h"#include "netrc.h"#include "debug.h"#include "ping.h"#define TCP_PING_PACKSIZE 3uerr_t tcp_ping(ping_t * ping_data){  unsigned int portnum;  int status, noblock, flags;  struct sockaddr_in server;  struct hostent *hp, hostbuf;  extern int h_errno;  /* int opt; */  char *tmphstbuf;  size_t hstbuflen = 2048;  struct timeval start_time;  struct timeval end_time;  char ping_buf[TCP_PING_PACKSIZE];  int bytes_read;  int standard_ping_milli_secs;  assert(ping_data->host);  tmphstbuf = kmalloc(hstbuflen);  portnum = ping_data->port;  memset((void *) &server, 0, sizeof(server));  hp = k_gethostname(ping_data->host, &hostbuf, &tmphstbuf, &hstbuflen);  if (hp == NULL)    return ping_data->err = HOSTERR;  memcpy((void *) &server.sin_addr, hp->h_addr, hp->h_length);  server.sin_family = hp->h_addrtype;  server.sin_port = htons(portnum);  /* Create a socket. */  if ((ping_data->sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 1)  {    kfree(tmphstbuf);    return ping_data->err = CONSOCKERR;  }  /* Experimental. */  flags = fcntl(ping_data->sock, F_GETFL, 0);  if (flags != -1)    noblock = fcntl(ping_data->sock, F_SETFL, flags | O_NONBLOCK);  else    noblock = -1;  /* get start time */  gettimeofday(&start_time, 0);  status =      connect(ping_data->sock, (struct sockaddr *) &server,	      sizeof(server));  if ((status == -1) && (noblock != -1) && (errno == EINPROGRESS))  {    fd_set writefd;    FD_ZERO(&writefd);    FD_SET(ping_data->sock, &writefd);    status =	select((ping_data->sock + 1), NULL, &writefd, NULL,	       &ping_data->timeout);    /* Do we need to retry if the err is EINTR? */    if (status > 0)    {      socklen_t arglen = sizeof(int);      if (getsockopt	  (ping_data->sock, SOL_SOCKET, SO_ERROR, &status, &arglen) < 0)	status = errno;      if (status != 0)	errno = status, status = -1;      if (errno == EINPROGRESS)	errno = ETIMEDOUT;    } else if (status == 0)      errno = ETIMEDOUT, status = -1;  }  if (status < 0)  {    close_sock(&ping_data->sock);    if (errno == ECONNREFUSED)    {      kfree(tmphstbuf);      return ping_data->err = CONREFUSED;    } else if (errno == ETIMEDOUT)    {      kfree(tmphstbuf);      return ping_data->err = PINGTIMEOUT;    } else    {      kfree(tmphstbuf);      return ping_data->err = CONERROR;    }  } else  {    flags = fcntl(ping_data->sock, F_GETFL, 0);    if (flags != -1)      fcntl(ping_data->sock, F_SETFL, flags & ~O_NONBLOCK);  }  /* setsockopt(*sock, SOL_SOCKET, SO_KEEPALIVE, (char *)&opt,     (int) sizeof(opt)); */  kfree(tmphstbuf);  /*So far so good connection established */  bytes_read =      krecv(ping_data->sock, ping_buf, TCP_PING_PACKSIZE, 0,	    &ping_data->timeout);  close_sock(&ping_data->sock);  proz_debug("bytes read = %d", bytes_read);  if (bytes_read == -1)  {    if (errno == ETIMEDOUT)      return ping_data->err = PINGTIMEOUT;    else      return ping_data->err = READERR;  }  if (bytes_read == 0 || bytes_read < TCP_PING_PACKSIZE)    return ping_data->err = READERR;  /* the end time */  gettimeofday(&end_time, 0);  proz_timeval_subtract(&ping_data->ping_time, &end_time, &start_time);  /*  standard_ping_milli_secs =(int)((((float)ping_data->ping_time.tv_usec/1000)+(((float)ping_data->ping_time.tv_sec)*1000))*3/(float)bytes_read);     ping_data->ping_time.tv_sec=standard_ping_milli_secs/1000;     ping_data->ping_time.tv_usec=standard_ping_milli_secs%1000;   */  return ping_data->err = PINGOK;}void proz_mass_ping(ftps_request_t * request){  request->mass_ping_running = TRUE;  if (pthread_create(&request->mass_ping_thread, NULL,		     (void *) &mass_ping, (void *) request) != 0)    proz_die(_("Error: Not enough system resources"));}void proz_cancel_mass_ping(ftps_request_t * request){  /*TODO Rewrite so that this will terminate the pingin threads as well */  request->mass_ping_running = FALSE;  pthread_cancel(request->mass_ping_thread);  pthread_join(request->mass_ping_thread,0);}void mass_ping(ftps_request_t * request){  int i, j, k = 0, num_iter, num_left, simul_pings;  pthread_t *ping_threads;  ping_t *ping_requests;  simul_pings = request->max_simul_pings;  pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);  ping_threads = (pthread_t *) kmalloc(sizeof(pthread_t) * simul_pings);  ping_requests = kmalloc(sizeof(ping_t) * request->num_mirrors);  num_iter = request->num_mirrors / simul_pings;  num_left = request->num_mirrors % simul_pings;  proz_debug("Max simul pings=%d", simul_pings);  proz_debug("request->num_mirrors=%d", request->num_mirrors);  pthread_mutex_lock(&request->access_mutex);  request->mass_ping_running = TRUE;  pthread_mutex_unlock(&request->access_mutex);  k = 0;  for (i = 0; i < num_iter; i++)  {    for (j = 0; j < simul_pings; j++)    {      ping_t ping_request;      memset(ping_requests + k, 0, sizeof(ping_request));      /*FIXME */      ping_requests[k].timeout.tv_sec = request->ping_timeout.tv_sec;      ping_requests[k].timeout.tv_usec = request->ping_timeout.tv_usec;      ping_requests[k].host = strdup(request->mirrors[k].server_name);      ping_requests[k].port = 21;      if (pthread_create(&ping_threads[j], NULL,			 (void *) &tcp_ping,			 (void *) (ping_requests + k)) != 0)	proz_die("Error: Not enough system resources"		 "to create thread!\n");      k++;    }    k -= simul_pings;    for (j = 0; j < simul_pings; j++)    {      /*Wait till the end of each thread. */      pthread_join(ping_threads[j], NULL);      if (ping_requests[k].err == PINGOK)      {	pthread_mutex_lock(&request->access_mutex);	request->mirrors[k].milli_secs =	    (ping_requests[k].ping_time.tv_sec * 1000) +	    (ping_requests[k].ping_time.tv_usec / 1000);	request->mirrors[k].status = RESPONSEOK;	pthread_mutex_unlock(&request->access_mutex);      } else      {	pthread_mutex_lock(&request->access_mutex);	request->mirrors[k].status = NORESPONSE;	pthread_mutex_unlock(&request->access_mutex);      }      k++;    }  }  for (j = 0; j < num_left; j++)  {    ping_t ping_request;    memset(ping_requests + k, 0, sizeof(ping_request));    /*FIXME */    ping_requests[k].timeout.tv_sec = request->ping_timeout.tv_sec;    ping_requests[k].timeout.tv_usec = 0;    ping_requests[k].host = strdup(request->mirrors[k].server_name);    ping_requests[k].port = 21;    if (pthread_create(&ping_threads[j], NULL,		       (void *) &tcp_ping,		       (void *) (&ping_requests[k])) != 0)      proz_die("Error: Not enough system resources" "to create thread!\n");    k++;  }  k -= num_left;  for (j = 0; j < num_left; j++)  {    /*Wait till the end of each thread. */    pthread_join(ping_threads[j], NULL);    /*Wait till the end of each thread. */    pthread_join(ping_threads[j], NULL);    if (ping_requests[k].err == PINGOK)    {      pthread_mutex_lock(&request->access_mutex);      request->mirrors[k].milli_secs =	  (ping_requests[k].ping_time.tv_sec * 1000) +	  (ping_requests[k].ping_time.tv_usec / 1000);      request->mirrors[k].status = RESPONSEOK;      pthread_mutex_unlock(&request->access_mutex);    } else    {      pthread_mutex_lock(&request->access_mutex);      request->mirrors[k].status = NORESPONSE;      pthread_mutex_unlock(&request->access_mutex);    }    k++;  }  pthread_mutex_lock(&request->access_mutex);  request->mass_ping_running = FALSE;  pthread_mutex_unlock(&request->access_mutex);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -