async2.c
上传用户:sddyfurun
上传日期:2007-01-04
资源大小:525k
文件大小:5k
源码类别:

代理服务器

开发平台:

Unix_Linux

  1. /* This code was written by Carson Gaspar, I've put it here just in case */
  2. /* anyone else has problems with non-blocking code...                    */
  3. #include "config.h"
  4. #include <sys/types.h>
  5. #include <sys/signal.h>
  6. #ifdef HAVE_SYS_SOCKET_H
  7. #include <sys/socket.h>
  8. #endif
  9. #ifdef HAVE_FCNTL_H
  10. #include <fcntl.h>
  11. #endif
  12. #include <netinet/in.h>
  13. #include <arpa/inet.h>
  14. #include <netdb.h>
  15. #include <stdio.h>
  16. #include <stdlib.h>
  17. #include <errno.h>
  18. #ifdef HAVE_SYS_TIME_H
  19. #include <sys/time.h>
  20. #endif
  21. #ifdef HAVE_STRING_H
  22. #include <string.h>
  23. #endif
  24. #ifdef HAVE_SYS_FILE_H
  25. #include <sys/file.h>
  26. #endif
  27. extern int h_errno;
  28. int main(int argc, char **argv)
  29. {
  30.   int mysock,status,numfds;
  31.   short port;
  32.   struct hostent *hent;
  33.   struct sockaddr_in mysa;
  34.   fd_set rfds,wfds,efds;
  35.   struct timeval mytv;
  36.   char buf;
  37.   if (argc < 3) {
  38.     fprintf(stderr, "Usage: %s hostname portn", argv[0]);
  39.     exit(255);
  40.   }
  41.   signal(SIGPIPE, SIG_IGN);
  42.   while ((hent = gethostbyname(argv[1])) == NULL) {
  43.     switch(h_errno) {
  44.     case HOST_NOT_FOUND:
  45.     case NO_RECOVERY:
  46.     case NO_DATA:
  47.       fprintf(stderr,"Host %s not foundn", argv[1]);
  48.       exit(255);
  49.       break;
  50.     case TRY_AGAIN:
  51.       fprintf(stderr,"Failed to get address of %s, retryingn", argv[1]);
  52.       break;
  53.     }
  54.   }
  55.   mysa.sin_family = AF_INET;
  56.   memcpy(&mysa.sin_addr, hent->h_addr, hent->h_length);
  57.   errno = 0;
  58.   port = (short) strtol(argv[2], NULL, 10);
  59.   if (errno != 0) {
  60.     perror("invalid port");
  61.     exit(255);
  62.   }
  63.   mysa.sin_port = htons(port);
  64.   if ((mysock = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
  65.     perror("socket failed");
  66.     exit(255);
  67.   }
  68.   if (fcntl(mysock, F_SETFL, FNDELAY)) {
  69.     perror("fcntl F_SETFL O_NONBLOCK failed");
  70.     exit(255);
  71.   }
  72.   status = 0;
  73.   if ((connect(mysock,(struct sockaddr *) &mysa, sizeof(mysa))) < 0) {
  74.     if ((errno != EALREADY) && (errno != EINPROGRESS)) {
  75.       perror("connect failed");
  76.       exit(255);
  77.     } else {
  78.       status = 1;
  79.       perror("connect status");
  80.     }
  81.   } else {
  82.     fprintf(stderr, "connection succeeded!n");
  83.     exit(0);
  84.   }
  85.   fprintf(stderr, "first connect cancelled (intentionally!)n");
  86.   close(mysock);
  87.   if ((mysock = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
  88.     perror("socket failed");
  89.     exit(255);
  90.   }
  91.   if (fcntl(mysock, F_SETFL, FNDELAY)) {
  92.     perror("fcntl F_SETFL O_NONBLOCK failed");
  93.     exit(255);
  94.   }
  95.   status = 0;
  96.   if ((connect(mysock,(struct sockaddr *) &mysa, sizeof(mysa))) < 0) {
  97.     if ((errno != EALREADY) && (errno != EINPROGRESS)) {
  98.       perror("connect failed");
  99.       exit(255);
  100.     } else {
  101.       status = 1;
  102.       perror("connect status");
  103.     }
  104.   } else {
  105.     fprintf(stderr, "connection succeeded!n");
  106.     exit(0);
  107.   }
  108.   while(status < 2) {
  109.     FD_ZERO(&rfds);
  110.     FD_ZERO(&wfds);
  111.     FD_ZERO(&efds);
  112.     FD_SET(mysock, &rfds);
  113.     FD_SET(mysock, &wfds);
  114.     mytv.tv_sec = 2;
  115.     mytv.tv_usec = 0;
  116.     while ((numfds = select(FD_SETSIZE - 1, &rfds, &wfds, &efds, &mytv)) < 0) {
  117. if (errno != EINTR) {
  118.     perror("select failed");
  119.     exit(255);
  120. }
  121. FD_ZERO(&rfds);
  122. FD_ZERO(&wfds);
  123. FD_ZERO(&efds);
  124. FD_SET(mysock, &rfds);
  125. FD_SET(mysock, &wfds);
  126.     }
  127.     if (numfds == 0) {
  128. fprintf(stderr, "select returned with no fdsn");
  129.     } else {
  130. if (FD_ISSET(mysock, &rfds)) {
  131.     fprintf(stderr, "select returned socket readablen");
  132.     if (argc > 3) {
  133. if (read(mysock, &buf, 1) < 0) {
  134.     perror("connect failed: read");
  135.     exit(255);
  136. } else {
  137.     fprintf(stderr, "read returned ok?!?n");
  138.     exit(255);
  139. }
  140.     }
  141.     if ((connect(mysock,(struct sockaddr *) &mysa, sizeof(mysa))) < 0) {
  142. fprintf(stderr, "connection is closedn");
  143. switch (errno) {
  144.     case ETIMEDOUT:
  145. fprintf(stderr, "connect() againn");
  146. exit(0);
  147.     case EISCONN:
  148. fprintf(stderr, "connection succeeded!?!n");
  149. exit(0);
  150.     case EINVAL:
  151.     case EPIPE:
  152. perror("connect()");
  153. if (read(mysock, &buf, 1) < 0) {
  154.     perror("connect failed: read");
  155.     exit(255);
  156. } else {
  157.     fprintf(stderr, "read returned ok?!?n");
  158.     exit(255);
  159. }
  160.     default:
  161. perror("connect failed");
  162. exit(255);
  163. }
  164.     }
  165.     fprintf(stderr, "connection succeeded?n");
  166. }
  167. if (FD_ISSET(mysock, &wfds)) {
  168.     fprintf(stderr, "select returned socket writeble - trying to connectn");
  169.     if ((connect(mysock,(struct sockaddr *) &mysa, sizeof(mysa))) < 0) {
  170. switch (errno) {
  171.     case EALREADY:
  172.     case EINPROGRESS:
  173. status = 1;
  174. perror("connect status");
  175. break;
  176.     case EISCONN:
  177. fprintf(stderr, "connection succeeded!n");
  178. exit(0);
  179. break;
  180.     default:
  181. perror("connect failed");
  182. exit(255);
  183. }
  184.     } else {
  185. fprintf(stderr, "connection succeeded!n");
  186. exit(0);
  187.     }
  188. }
  189.     }
  190.   }
  191.   /* we should never get here */
  192.   exit(1);
  193. }