您的位置:首页 > 运维架构 > Linux

Linux下非阻塞connect

2015-03-14 18:02 169 查看
#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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: