zoukankan      html  css  js  c++  java
  • [原创]C 语言select函数

    参考链接:http://www.cnblogs.com/GameDeveloper/p/3406565.html

    注意点: select() 只是执行一次的超时检测。重新进行select要重新设置“超时时间”以及“句柄”。

    connect 非阻塞的例子:

    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <time.h>
    #include <fcntl.h>
    #include <errno.h>
    #include <string.h>
    
    
    
    
    int main(int argc, char** argv)
    {
    int sockfd,recvbytes,res,flags,error=-1,n;
    socklen_t len;
    fd_set rset,wset;
    struct timeval tval;
    struct sockaddr_in serv_addr;
    char*sendData="1234567890";//发送字符串
    char buf[1024]="/0"; //接收buffer
    //创建socket描述符
    if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
    {
    perror("socket create failed");
    return 1;
    }
    
    serv_addr.sin_family=AF_INET;
    serv_addr.sin_port=htons(9999);
    serv_addr.sin_addr.s_addr=inet_addr("172.16.0.111");
    bzero(&(serv_addr.sin_zero),8);
    flags=fcntl(sockfd,F_GETFL,0);
    fcntl(sockfd,F_SETFL,flags|O_NONBLOCK);//设置为非阻塞
    
    if( (res = connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(struct sockaddr)) )< 0)
    {
        if(errno != EINPROGRESS)
        {
        return 1;
        }
    
    }
    
    //如果server与client在同一主机上,有些环境socket设为非阻塞会返回 0
    // if(0 == res) goto done;
    
    while(error!=0){
    
    tval.tv_sec=0;
    tval.tv_usec=3000000;   //要在while重新设置时间,否则超时不生效
    FD_ZERO(&rset);            //要在while重新添加句柄,否则检测不了变化
    FD_SET(sockfd,&rset);
    wset=rset;
    printf("enter while
    ");
    
    res = select(sockfd+1, NULL, &wset, NULL,&tval) ;
    if( res == 0)
    {
        perror("connect time out
    ");
        // close(sockfd);
        // return 1;
    }
    else 
    {
        if(res>0){
    
        len=sizeof(error);
        getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, &len);
    
        printf("error:%d
    ", error);
        if(error)
        {
          fprintf(stderr, "Error in connection() %d - %s
    ", error, strerror(error));
          // return 1;
        }
    
        }
    
        
    }
    }
    
    if(res !=0)
      {
        printf("done
    ");
        if( (n = send(sockfd, sendData, strlen(sendData),0) ) ==-1 )
        {
    
            perror("send error!");
            close(sockfd);
            return 1;
        }
        if( ( n = select(sockfd+1,&rset,NULL, NULL,&tval)) <= 0 )//rset没有使用过,不用重新置为sockfd
        {
            perror("receive time out or connect error");
            close(sockfd);
            return -1;
        }
        if((recvbytes=recv(sockfd, buf, 1024, 0)) ==-1)
        {
            perror("recv error!");
            close(sockfd);
            return 1;
        }
    
      
        printf("receive num %d
    ",recvbytes);
        printf("%s
    ",buf);
    
        }
    }
  • 相关阅读:
    Linux_进程之间的通信
    Linux_控制作业(管理)
    Linux_进程管理相关命令
    Linux_进程管理的基本概述
    文本编辑_Vim&Vi
    Linux_权限管理理论概述
    Linux_用户和组管理
    Linux_ACL文件访问控制列表
    72. VUE axios 配置信息相关
    71. VUE axios 发送并发请求(多个)
  • 原文地址:https://www.cnblogs.com/hzijone/p/5852006.html
Copyright © 2011-2022 走看看