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

linux socket connect超时设置

2013-03-14 14:01 417 查看
本帖最后由 fs_te_ming 于 2013-03-14 14:04 编辑突然想想试试看,linux下的connect超时,两种方式实现

1)sigaction

#include <stdio.h>

#include <stdlib.h>

#include <errno.h>

#include <string.h>

#include <sys/types.h>

#include <netdb.h>

#include <netinet/in.h>

#include <sys/socket.h>

#include <sys/wait.h>

#include <sys/time.h>

#include <unistd.h>

#include <asm/ioctls.h>

#include <signal.h>

#define SERVPORT 13333

#define TIMEOUT_TIME 6

void connect_sigalarm()

{

printf("connect alarm.\n");

return;

}

int main(int argc,char *argv[])

{

int sockfd;

int retval;

int error=-1;

char *dest_ip;

int ret=0;

struct sockaddr_in serv_info;

struct sigaction act,oldact;

struct timeval tm;

fd_set rset,wset;

char buf[1024];

if(argc == 2)

{

dest_ip=argv[1];

}

act.sa_handler = connect_sigalarm;

sigemptyset(&act.sa_mask);

sigaddset(&act.sa_mask, SIGALRM);

act.sa_flags = SA_INTERRUPT; //由此信号中断的系统调用不会自动重启

sigaction(SIGALRM, &act, &oldact);

if(alarm(5) != 0)

{

printf("alarm has already set.\n");

}

memset(&serv_info,0,sizeof(serv_info));

serv_info.sin_family = AF_INET;

serv_info.sin_port = htons(SERVPORT);

serv_info.sin_addr.s_addr = inet_addr(dest_ip);

sockfd = socket(PF_INET,SOCK_STREAM,0);

if(sockfd<0)

{

perror("socket");

return 1;

}

if(connect(sockfd,(struct sockaddr *)&serv_info,sizeof(struct sockaddr))<0)

{

close(sockfd);

if (errno == EINTR)

{

//errno=TIMEOUT;

printf("connect timeout\n");

}

}

alarm(0);

return 0;

}

2)非阻塞的select

#include <stdio.h>

#include <stdlib.h>

#include <errno.h>

#include <string.h>

#include <sys/types.h>

#include <netdb.h>

#include <netinet/in.h>

#include <sys/socket.h>

#include <sys/wait.h>

#include <sys/time.h>

#include <unistd.h>

#include <asm/ioctls.h>

#include <signal.h>

#include <fcntl.h>

#define SERVPORT 13333

#define TIMEOUT_TIME 6

int main(int argc,char *argv[])

{

int sockfd;

int retval;

int error=-1;

char *dest_ip;

int len;

int ret=0;

struct sockaddr_in serv_info;

struct sigaction act,oldact;

struct timeval tm;

fd_set rset,wset;

char buf[1024];

if(argc == 2)

{

dest_ip=argv[1];

}

memset(&serv_info,0,sizeof(serv_info));

serv_info.sin_family = AF_INET;

serv_info.sin_port = htons(SERVPORT);

serv_info.sin_addr.s_addr = inet_addr(dest_ip);

sockfd = socket(PF_INET,SOCK_STREAM,0);

if(sockfd<0)

{

perror("socket");

return 1;

}

if(fcntl(sockfd,F_SETFL,fcntl(sockfd,F_GETFL) | O_NONBLOCK)<0)

{

perror("fcntl");

close(sockfd);

return 1;

}

if(connect(sockfd,(struct sockaddr *)&serv_info,sizeof(struct sockaddr))<0)

{

if(errno != EINPROGRESS)

{

perror("connect");

return 1;

}

tm.tv_sec = TIMEOUT_TIME;

tm.tv_usec = 0;

FD_ZERO(&wset);

FD_SET(sockfd,&wset);

retval = select(sockfd+1,NULL,&wset,NULL,&tm);

switch(retval)

{

case -1:

perror("select");

return 1;

case 0:

printf("timeout\n");

break;

default:

if(FD_ISSET(sockfd,&wset))

{

if(getsockopt(sockfd,SOL_SOCKET,SO_ERROR,&error,(socklen_t *)&len)<0)

{

return 1;

}

printf("error=%d\n",error);

if(error==0)

{

ret=1;

}

else

{

ret=0;

errno=error;

}

}

break;

}

}

fcntl(sockfd,F_SETFL,fcntl(sockfd,F_GETFL) & O_NONBLOCK); //set back to block mode

if(!ret)

{

close(sockfd);

perror("connect failed");

return 1;

}

sprintf(buf,"%s","hello world!");

if(send(sockfd,buf,strlen(buf),0)<0)

{

perror("send");

}

printf("connected\n");

return 0;

}

均已测试通过,测试方式,服务端监听端口13333,设置iptables drop所有连接到这个端口的连接;客户端发起连接
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: