Linux下非阻塞connect

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <assert.h>
#include <stdio.h>
#include <time.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <string.h>

#define BUFFER_SIZE 1023

int setnonblocking(int fd)
{
    int old_option=fcntl(fd,F_GETFL);
    int new_option=old_option | O_NONBLOCK;
    fcntl(fd,F_SETFL,new_option);
    return old_option;
}

int unblock_connect(const char *ip,int port,int time)
{
    int ret=0;
    struct sockaddr_in address;
    bzero(&address,sizeof(address));
    address.sin_family=AF_INET;
    inet_pton(AF_INET,ip,&address.sin_addr);
    address.sin_port=htons(port);

    int sockfd=socket(PF_INET,SOCK_STREAM,0);
    int fdopt=setnonblocking(sockfd);
    ret=connect(sockfd,(struct sockaddr *)&address,sizeof(address));
    if(ret==0)
    {
        printf("connect with server immediately\n");
        fcntl(sockfd,F_SETFL,fdopt);
        return sockfd;
    }
    else if(errno!=EINPROGRESS)
    {
        printf("unblock connect not support\n");
        return -1;
    }
    fd_set readfds;
    fd_set writefds;
    struct timeval timeout;
    timeout.tv_sec=time;
    timeout.tv_usec=0;

    ret=select(sockfd+1,NULL,&writefds,NULL,&timeout);
    if(ret<=0)
    {
        printf("connection time out\n");
        close(sockfd);
        return -1;
    }
    if(!FD_ISSET(sockfd,&writefds))
    {
        printf("no events on sockfd found\n");
        close(sockfd);
        return -1;
    }

    int error=0;
    socklen_t length=sizeof(error);
    if(getsockopt(sockfd,SOL_SOCKET,SO_ERROR,&error,&length)<0)
    {
        printf("get socket option failed");
        close(sockfd);
        return -1;
    }
    if(error!=0)
    {
        printf("connection failed after select with the error:% d \n",error);
        close(sockfd);
        return -1;
    }
    printf("connection ready after select with the socket:  %d \n",sockfd);
    fcntl(sockfd,F_SETFL,fdopt);
    return sockfd;
}

int main()
{
    const char *ip="127.0.0.1";
    int port=12345;
    int sockfd=unblock_connect(ip,port,10);
    if(sockfd<0)
    {
        return 1;
    }
    close(sockfd);
    return 0;
}

时间: 2024-08-06 09:59:22

Linux下非阻塞connect的相关文章

linux 非阻塞 connect函数

开发测试环境:虚拟机CentOS,windows网络调试助手        非阻塞模式有3种用途        1.三次握手同时做其他的处理.connect要花一个往返时间完成,从几毫秒的局域网到几百毫秒或几秒的广域网.这段时间可能有一些其他的处理要执行,比如数据准备,预处理等.        2.用这种技术建立多个连接.这在web浏览器中很普遍.        3.由于程序用select等待连接完成,可以设置一个select等待时间限制,从而缩短connect超时时间.多数实现中,connec

面向连接的socket数据处理过程以及非阻塞connect问题

对于面向连接的socket类型(SOCK_STREAM,SOCK_SEQPACKET)在读写数据之前必须建立连接,首先服务器端socket必须在一个客户端知道的地址进行监听,也就是创建socket之后必须调用bind绑定到一个指定的地址,然后调用int listen(int sockfd, int backlog);进行监听.此时服务器socket允许客户端进行连接,backlog提示没被accept的客户连接请求队列的大小,系统决定实际的值,最大值定义为SOMAXCONN在头文件<sys/so

(转)非阻塞Connect对于select时应注意问题

对于面向连接的socket类型(SOCK_STREAM,SOCK_SEQPACKET)在读写数据之前必须建立连接,首先服务器端socket必须在一个客户端知道的地址进行监听,也就是创建socket之后必须调用bind绑定到一个指定的地址,然后调用int listen(int sockfd, int backlog);进行监听.此时服务器socket允许客户端进行连接,backlog提示没被accept的客户连接请求队列的大小,系统决定实际的值,最大值定义为SOMAXCONN在头文件<sys/so

非阻塞connect

步骤1: 设置非阻塞,启动连接 实现非阻塞 connect ,首先把 sockfd 设置成非阻塞的.这样调用 connect 可以立刻返回,根据返回值和 errno 处理三种情况: (1) 如果返回 0,表示 connect 成功. (2) 如果返回值小于 0, errno 为 EINPROGRESS, 表示连接 建立已经启动但是尚未完成.这是期望的结果,不是真正的错误. (3) 如果返回值小于0,errno 不是 EINPROGRESS,则连接出错了. 步骤2:判断可读和可写 然后把 sock

由select/epoll返回的非阻塞connect还会是EINPROGRESS状态吗?

一般情况下,我们像下面代码中所示的这样使用非阻塞connect: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75

TCP非阻塞accept和非阻塞connect

http://blog.chinaunix.net/uid-20751538-id-238260.html 非阻塞accept 当一个已完成的连接准备好被accept的时候,select会把监听socket标记为可读.因此,如果用select等待外来的连接时,应该不需要 把监听socket设置为非阻塞模式,因为如果select告诉我们连接已经就绪,accept就不应该被阻塞.不过这样做的时候有一个BUG:当客户端 在跟服务器建立连接之后发送了一个RST包,这个时候accept就会阻塞,直到有下一

TCP之非阻塞connect和accept

套接字的默认状态是阻塞的,这就意味着当发出一个不能立即完成的套接字调用时,其进程将被投入睡眠,等待响应操作完成,可能阻塞的套接字调用可分为以下四类: (1) 输入操作,包括read,readv,recv,recvfrom,recvmsg: (2) 输出操作,包括write,writev,send,sendto,sendmsg: (3) 接受外来连接,即accept函数. (4) 发起外出连接,即tcp的connect函数: 非阻塞connect: 当一个非阻塞的tcp套接字上调用connect时

UNIX网络编程-非阻塞connect和非阻塞accept

1.非阻塞connect 在看了很多资料之后,我自己的理解是:在socket发起一次连接的时候,这个过程需要一段时间来将三次握手的过程走完,如果在网络状况不好或者是其他的一些情况下,这个过程需要比较长的时间,我们在连接之前将socket设置为非阻塞模式之后,调用connect函数之后,立即返回,如果成功返回0,如果不成功则返回EINPROGRESS,这个值表明连接正在进行,我们可以设置一个超时时间,然后在这个时间段内不停的检查socket是否连接上了,如果在这个时间段内还没有连上,则返回失败.在

时间获取程序客户端 TCP 使用非阻塞connect

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie /** * TCP,使用非阻塞 connect **/ #include "unp.h" int connect_nonb(int sockfd, const SA *saptr, socklen_t salen, int nsec) { int flags, n, error; socklen_t len; fd_set rset, wset; struct timeval t