首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C语言 >

使用 select 设计超时 connect 函数的有关问题(linux 上连接 127.0.0.1 任何端口总是成功)

2012-02-15 
使用 select 设计超时 connect 函数的问题(linux 上连接 127.0.0.1 任何端口总是成功)#includestdlib.h#

使用 select 设计超时 connect 函数的问题(linux 上连接 127.0.0.1 任何端口总是成功)
#include   <stdlib.h>
#include   <stdio.h>
#include   <unistd.h>
#include   <fcntl.h>
#include   <sys/types.h>
#include   <sys/socket.h>
#include   <netinet/in.h>
#include   <errno.h>
#include   <time.h>
#include   <arpa/inet.h>

int   main(int   argc,   char   *argv[])  
{
int   fd,   retval;  
struct   sockaddr_in   addr;
struct   timeval   timeo   =   {3,   0};  
socklen_t   len   =   sizeof(timeo);
fd_set   set;  

fd   =   socket(AF_INET,   SOCK_STREAM,   0);
if   (argc   ==   4)   timeo.tv_sec   =   atoi(argv[3]);  
int   savefl   =   fcntl(fd,F_GETFL);
fcntl(fd,   F_SETFL,   savefl   |   O_NONBLOCK);
addr.sin_family   =   AF_INET;
addr.sin_addr.s_addr   =   inet_addr(argv[1]);
addr.sin_port   =   htons(atoi(argv[2]));
printf( "%d\n ",   time(NULL));  
if   (connect(fd,   (struct   sockaddr*)&addr,   sizeof(addr))   ==   0)  
{  
close(fd);
printf( "connected..1\n ");
return   0;  
}

if   (errno   !=   EINPROGRESS)
{
close(fd);
perror( "connect..2 ");
return   -1;  
}
FD_ZERO(&set);
FD_SET(fd,   &set);
retval   =   select(fd   +   1,   NULL,   &set,   NULL,   &timeo);  
if   (retval   ==   -1)
{  
close(fd);
perror( "select ");  
return   -1;
}  
else   if(retval   ==   0)  
{  
close(fd);
fprintf(stderr,   "timeout\n ");
printf( "%d\n ",   time(NULL));
return   0;
}
printf( "connected   ..   3\n ");
fcntl(fd,   F_SETFL,savefl);
close(fd);
return   0;  
}

1.   OS:linux   kenerl   2.6   (fedora.unix-center.net)
2.   测试连接   (202.108.22.43:80,202.108.22.43:8000,)   百度,程序正常,其他机器也正常
3.   但是测试   127.0.0.1   任何端口都说能连接上,非常奇怪




[解决办法]
用netstat看是连上的么?
[解决办法]
fcntl(fd, F_SETFL, savefl | O_NONBLOCK);

//你把他设置成非阻塞方式啦,

你的判断方式有点问题:
if (connect(fd, (struct sockaddr*)&addr, sizeof(addr)) == 0)//成功就退出?那下面的其他代码都是在连接失败情况下的处理,有何意义?
{
close(fd);
printf( "connected..1\n ");
return 0;
}
[解决办法]
retval = select(fd + 1, NULL, &set, NULL, &timeo);

retval=1的時候未必連接得上,
當retval=1得時候還要判斷errno的值是不是0
[解决办法]
retval=1
是很正常, 比如你要connect的時候應該經過3次握手

當connect寫的時候基本就可以說建立成功了

但是一個特例就是有firewall阻擋的話connect依然會去write

你的問題可以通過抓取packet來解決.

热点排行