Socket非阻塞连接过程

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <strings.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>

static fd_set                rset;
static fd_set                wset;

int CanRead(int sockfd)
{
    FD_ZERO(&rset);
    FD_SET(sockfd, &rset);

    struct timeval        tval;
    int n;
    tval.tv_sec =   30;
    tval.tv_usec = 0;
    if ((n = select(sockfd + 1, &rset, NULL, NULL, &tval)) == 0) {
        printf("timeout\n");
        return 0;
    }
    if (FD_ISSET(sockfd, &rset)) {
        int error;
        int len = sizeof(error);
        if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, &len) < 0) {
            perror("getsockopt\n");
            return 0;
        }
        return 1;
    }
    else {
        perror("select error, socket fd not set\n");
        return 0;
    }
}
int CanWrite(int sockfd)
{
    FD_ZERO(&wset);
    FD_SET(sockfd, &wset);

    struct timeval        tval;
    int n;
    tval.tv_sec =   30;
    tval.tv_usec = 0;
    if ((n = select(sockfd + 1, NULL, &wset, NULL, &tval)) == 0) {
        printf("timeout\n");
        return 0;
    }
    if (FD_ISSET(sockfd, &wset)) {
        int error;
        int len = sizeof(error);
        if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, &len) < 0) {
            perror("getsockopt\n");
            return 0;
        }
        return 1;
    }
    else {
        perror("select error, socket fd not set\n");
        return 0;
    }
}
int ConnecToHost(int sockfd,char* ip,int port)
{
    struct sockaddr_in     *st_in;
    struct sockaddr        servaddr;
    st_in = (struct sockaddr_in *)&servaddr;
    bzero(st_in, sizeof(servaddr));
    st_in->sin_family = AF_INET;
    st_in->sin_port = htons(port);
    inet_pton(AF_INET, ip, &st_in->sin_addr);
    printf("connect to %s:%d....\n", ip, port);

    int n=0;
    if ((n = connect(sockfd, &servaddr, sizeof(servaddr))) < 0) {
        if (errno != EINPROGRESS) {
            perror("connect");
            return 0;
        }
    }
    if (n == 0)
    {
        printf("connected immediately\n");
        return 1;
    }
    printf("connectting\n");
    while(1)
    {
        FD_ZERO(&rset);
        FD_SET(sockfd, &rset);
        wset = rset;

        struct timeval        tval;
        int n;
        tval.tv_sec =   30;
        tval.tv_usec = 0;
        if ((n = select(sockfd + 1, &rset, &wset, NULL, &tval)) == 0) {
            printf("timeout\n");
            continue;
        }
        if (FD_ISSET(sockfd, &rset) || FD_ISSET(sockfd, &wset)) {
            int error;
            int len = sizeof(error);
            if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, &len) < 0) {
                perror("getsockopt\n");
                continue;
            }
            printf("error :%d\n",error);
            if(error!=0)
            {
                continue;
            }
            printf("connectted\n");
            return 1;
        }
        else {
            perror("select error, socket fd not set\n");
            continue;
        }
    }
}
int main(int argc,char *argv[])
{
    char                 str[30];
    if (argc != 2) {
        printf("usage:need ip:port\n");
        return 0;
    }
    strncpy(str, argv[1], 30);
    str[29] = 0;
    char* ptr = strchr(str, ':');
    if(ptr==NULL)
    {
            printf("usage:need ip:port\n");
            return 0;
    }
    *ptr = '\0';
    int dstport = atoi(ptr + 1);

    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0) {
        perror("socket error\n");
        return 0;
    }
    int flags = fcntl(sockfd, F_GETFL, 0);  //获取设置
    if (flags == -1) {
        perror("fcntl\n");
        return 0;
    }
    fcntl(sockfd, F_SETFL, flags | O_NONBLOCK); //设置成非阻塞

    if(ConnecToHost(sockfd,str,dstport)==false)                     //连接
        return 0;

    if(CanWrite(sockfd))   //写
    {
        char buffer[128];
        sprintf(buffer, "GetDeviceInfo()");
        int len = send(sockfd, buffer, strlen(buffer), 0);
        printf("sent %d\n",len);
        if(len<0) {
            printf("send fail\n");
            return 0;
        }
    }
    if(CanRead(sockfd)) //读
    {
        char buffer[128];
        int len = recv(sockfd, buffer, sizeof(buffer), 0);
        printf("recv %d\n",len);
        if(len<0)
        {
            printf("recv fail");
        }
    }

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值