Chinaunix

标题: c语言中socket的问题 [打印本页]

作者: nmcny    时间: 2004-01-27 20:55
标题: c语言中socket的问题
我在sco unix 下建立了一个socket 的stream连接,使用connect函数时,如何设置超时时间
作者: hsia    时间: 2004-01-28 02:14
标题: c语言中socket的问题
可以在论坛内搜一下,然后再提问。
作者: forest077    时间: 2004-01-29 18:20
标题: c语言中socket的问题
可以使用alarm函数设置超时时间。
作者: FH    时间: 2004-01-29 20:36
标题: c语言中socket的问题
使用non-blocking I/O比用超时更好,不妨试试看。
作者: nmcny    时间: 2004-01-30 09:42
标题: c语言中socket的问题
无阻塞io是不是只有在调用connect函数成功后才能使用,我想知道怎么设置connect函数的超时时间,一般的话,连接一台不能提供服务器功能的机器会需要大概3分钟的时间,才能得到connect不成功的返回值.原来我想用线程来实现延时功能,但是在sco unix下没找到libthread库,是不是此操作系统下不支持,还是库名不对,望各位大侠帮忙!
作者: wjywhl    时间: 2004-01-30 11:30
标题: c语言中socket的问题
SCO不支持Thread
作者: forest077    时间: 2004-01-30 17:57
标题: c语言中socket的问题
在connect之前调用一下alarm设置一下超时时间,在connect之后调用一下alarm(0)清空定时器即可。
作者: kys2002    时间: 2004-01-31 14:42
标题: c语言中socket的问题
用select函数吧
作者: nmcny    时间: 2004-01-31 21:21
标题: c语言中socket的问题
forest077你的方法应该可以,我试一试,多谢
作者: mills    时间: 2004-02-02 09:37
标题: c语言中socket的问题
网络编程第一卷上有例子的
作者: jianyan    时间: 2004-02-02 22:22
标题: c语言中socket的问题


  1. 以下是PHP源代码中FTP的东东,自已看一下就知道了
  2. /*
  3. * Fills the any (wildcard) address into php_sockaddr_storage
  4. */
  5. void ftp::any_addr(int family, sockaddr_storage *addr, unsigned short port){
  6.     memset(addr, 0, sizeof(sockaddr_storage));
  7.     switch (family) {
  8.     case AF_INET: {
  9.         struct sockaddr_in *sin = (struct sockaddr_in *) addr;
  10.         sin->;sin_family = AF_INET;
  11.         sin->;sin_port = htons(port);
  12.         sin->;sin_addr.s_addr = htonl(INADDR_ANY);
  13.         break;
  14.     }
  15.     }
  16. }



  17. /*
  18. *  Returns the size of struct sockaddr_xx for the family
  19. */
  20. int ftp::sockaddr_size(sockaddr_storage *addr){
  21.     switch (((struct sockaddr *)addr)->;sa_family) {
  22.     case AF_INET:
  23.         return sizeof(struct sockaddr_in);
  24. #ifdef AF_UNIX
  25.     case AF_UNIX:
  26.         return sizeof(struct sockaddr_un);
  27. #endif
  28.     default:
  29.         return 0;
  30.     }
  31. }



  32. int ftp::connect_nonb(int sockfd,const struct sockaddr *addr,
  33.                        socklen_t addrlen, struct timeval *timeout){

  34.     int flags;
  35.     int n;
  36.     int error = 0;
  37.     socklen_t len;
  38.     int ret = 0;
  39.     fd_set rset;
  40.     fd_set wset;
  41.     fd_set eset;

  42.     if (timeout == NULL)    {
  43.         /* blocking mode */
  44.             return connect(sockfd, addr, addrlen);
  45.     }
  46.    
  47.     flags = fcntl(sockfd, F_GETFL, 0);
  48.     fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);

  49.     if ((n = connect(sockfd, addr, addrlen)) < 0) {
  50.         if (errno != EINPROGRESS) {
  51.             return -1;
  52.         }
  53.     }
  54.     if (n == 0) {
  55.         goto ok;
  56.     }

  57. #ifdef __linux__
  58. retry_again:
  59. #endif
  60.    
  61.     FD_ZERO(&rset);
  62.     FD_ZERO(&eset);
  63.     FD_SET(sockfd, &rset);
  64.     FD_SET(sockfd, &eset);

  65.     wset = rset;

  66.     if ((n = select(sockfd + 1, &rset, &wset, &eset, timeout)) == 0) {
  67.         error = ETIMEDOUT;
  68.     } else if ((FD_ISSET(sockfd, &rset) || FD_ISSET(sockfd, &wset))) {
  69.         len = sizeof(error);
  70.         /*
  71.            BSD-derived systems set errno correctly
  72.            Solaris returns -1 from getsockopt in case of error
  73.            */
  74.         if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, &len) < 0) {
  75.             ret = -1;
  76.         }
  77.     } else {
  78.         /* whoops: sockfd has disappeared */
  79.         ret = -1;
  80.         error = errno;
  81.     }

  82. #ifdef __linux__
  83.     /* this is a linux specific hack that only works since linux updates
  84.      * the timeout struct to reflect the time remaining from the original
  85.      * timeout value.  One day, we should record the start time and calculate
  86.      * the remaining time ourselves for portability */
  87.     if (ret == -1 && error == EINPROGRESS) {
  88.         error = 0;
  89.         goto retry_again;
  90.     }
  91. #endif
  92.    
  93. ok:
  94.     fcntl(sockfd, F_SETFL, flags);

  95.     if (error) {
  96.         errno = error;
  97.         ret = -1;
  98.     }
  99.     return ret;
  100. }



  101. int ftp::getaddresses(const char *host, int socktype, struct sockaddr ***sal ){
  102.     struct sockaddr **sap;
  103.     int n;
  104. #ifdef HAVE_GETADDRINFO
  105.     static int ipv6_borked = -1; /* the way this is used *is* thread safe */
  106.     struct addrinfo hints, *res, *sai;
  107. #else
  108.     struct hostent *host_info;
  109.     struct in_addr in;
  110. #endif
  111.     if (host == NULL) {
  112.         return 0;
  113.     }

  114. #ifdef HAVE_GETADDRINFO
  115.     memset(&hints, '\0', sizeof(hints));
  116.         
  117.     hints.ai_family = AF_INET; /* default to regular inet (see below) */
  118.     hints.ai_socktype = socktype;
  119.    
  120.     if ((n = getaddrinfo(host, NULL, &hints, &res))) {
  121.         printf("getaddresses: getaddrinfo failed: ");
  122.         
  123.         return 0;
  124.     } else if (res == NULL) {
  125.         printf("getaddresses: getaddrinfo failed (null result pointer)");
  126.         return 0;
  127.     }

  128.     sai = res;
  129.     for (n = 1; (sai = sai->;ai_next) != NULL; n++)
  130.         ;
  131.    
  132.     *sal = (sockaddr**) malloc((n + 1)* sizeof(*sal));
  133.     sai = res;
  134.     sap = *sal;
  135.    
  136.     do {
  137.         *sap = (sockaddr*) malloc(sai->;ai_addrlen);
  138.         memcpy(*sap, sai->;ai_addr, sai->;ai_addrlen);
  139.         sap++;
  140.     } while ((sai = sai->;ai_next) != NULL);
  141.    
  142.     freeaddrinfo(res);
  143. #else
  144.     if (!inet_aton(host, &in)) {
  145.         /* XXX NOT THREAD SAFE (is safe under win32) */
  146.         host_info = gethostbyname(host);
  147.         if (host_info == NULL) {
  148.             printf("getaddresses: gethostbyname failed");
  149.             return 0;
  150.         }
  151.         in = *((struct in_addr *) host_info->;h_addr);
  152.     }

  153.     *sal = (sockaddr**) malloc(2 * sizeof(*sal));
  154.     sap = *sal;
  155.     *sap = (sockaddr*)malloc(sizeof(struct sockaddr_in));
  156.     (*sap)->;sa_family = AF_INET;
  157.     ((struct sockaddr_in *)*sap)->;sin_addr = in;
  158.     sap++;
  159.     n = 1;
  160. #endif
  161.    
  162.     *sap = NULL;
  163.     return n;
  164.    
  165. }

  166. void ftp::freeaddresses(struct sockaddr **sal)
  167. {
  168.     struct sockaddr **sap;

  169.     if (sal == NULL)
  170.         return;
  171.     for (sap = sal; *sap != NULL; sap++)
  172.         free(*sap);
  173.     free(sal);
  174. }
  175.   
  176.   
  177. int ftp::hostconnect(string host, int port ,int socktype, struct timeval *timeout){
  178.     int n, repeatto, s;
  179.     struct sockaddr **sal, **psal;
  180.     struct timeval individual_timeout;
  181.     int set_timeout = 0;
  182.     int err = 0;
  183.     n = getaddresses(host.c_str(), socktype, &sal);
  184.     if (n == 0)
  185.         return -1;
  186.     if (timeout != NULL) {
  187.         /* is this a good idea? 5s? */
  188.         repeatto = timeout->;tv_sec / n >; 5;
  189.         if (repeatto) {
  190.             individual_timeout.tv_sec = timeout->;tv_sec / n;
  191.         } else {
  192.             individual_timeout.tv_sec = timeout->;tv_sec;
  193.         }

  194.         individual_timeout.tv_usec = timeout->;tv_usec;
  195.     } else {
  196.         individual_timeout.tv_sec = 0;
  197.         individual_timeout.tv_usec = 0;
  198.     }
  199.    
  200.     /* Boolean indicating whether to pass a timeout */
  201.     set_timeout = individual_timeout.tv_sec + individual_timeout.tv_usec;
  202.    
  203.     psal = sal;
  204.     while (*sal != NULL) {
  205.         s = socket((*sal)->;sa_family, socktype, 0);
  206.         if (s != SOCK_ERR) {
  207.             switch ((*sal)->;sa_family) {
  208.                 case AF_INET:
  209.                     {
  210.                         struct sockaddr_in *sa =
  211.                             (struct sockaddr_in *)*sal;

  212.                         sa->;sin_family = (*sal)->;sa_family;
  213.                         sa->;sin_port = htons(port);
  214.                         if (this->;connect_nonb(s, (struct sockaddr *) sa,
  215.                                     sizeof(*sa), (set_timeout) ? &individual_timeout : NULL) != SOCK_CONN_ERR)
  216.                             goto ok;
  217.                     }
  218.                     break;
  219.             }
  220.             err = errno;
  221.             ::close (s);
  222.         }
  223.         sal++;

  224.         if (err == TIMEOUT_ERROR_VALUE) {
  225.             /* if the first attempt timed out, it's highly likely
  226.              * that any subsequent attempts will do so also */
  227.             break;
  228.         }
  229.         
  230.     }
  231.     this->;freeaddresses(psal);
  232.     return -1;

  233. ok:
  234.     this->;freeaddresses(psal);
  235.     return s;
  236.    
  237. }


复制代码





欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2