免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2973 | 回复: 4
打印 上一主题 下一主题

socket客户端连接超时问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-05-10 08:33 |只看该作者 |倒序浏览
本帖最后由 babycat_fei 于 2012-05-10 09:46 编辑

客户端程序:
#include...
#include...
#include...
#include...
#include...
#include...


typedef struct{
   unsigned char code;
   unsigned char len;
   unsigned char offset;
   unsigned long address[1];
}LSR;

int main()
{
   
    LSR sourceRoute;
    memset(&sourceRoute,'\0',sizeof(LSR));
    sourceRoute.code = 0x83;
    sourceRoute.len = 7;
    sourceRoute.offset = 4;
    sourceRoute.address[0] = inet_addr("ip_inter");//ip_inter为中间节点的ip

    fd = socket(AF_INET,SOCK_STREAM,0);
    sevaddr.sin_family = AF_INET;
    sevaddr.sin_addr.s_addr= inet_addr("ip");//ip为源节点ip
    sevaddr.sin_port = htons(6100);
   
//加上下面这句设置ip选项为源路由就连接超时了,去掉就可以成功连接
    setsockopt(fd, IPPROTO_IP, IP_OPTIONS, (char*)$sourceRoute, sourceRoute.len);
   
    connect(fd, (struct sockaddr *)&sevaddr, sizeof(sevaddr));

    write(...);
    read(...);
    close(fd);
    return 1;
}
阻塞模式,客户端connect时,总是返回EINPROGRESS,查看了一下端口状态卡在SYN_SENT,连接不上;改为非阻塞模式connect时,select返回0,连接超时。去掉setsockopt设置源路由那句一切正常,但查看了一下这个函数的返回值是正确的,不知为什么设了源路由后就连接不上了,网络都可以ping通。

论坛徽章:
0
2 [报告]
发表于 2012-05-10 15:12 |只看该作者
本帖最后由 virusest 于 2012-05-10 15:46 编辑

你的len长度不对,对于只有1个IP地址的宽松的源站选路来说,len的长度是11, 包括一个选路IP(4字节),code(1字节),len(1字节),ptr(1字节),还有一个最后的目的IP地址(4字节),当源站选路的第一个IP被设置为报文的目的地址后,len会减4;所以,下一个路由器发现这个len变为3, 会丢弃这个报文的。。。

其实,你的sourceRoute结构体里至少得有2个IP地址,一个中间选路IP地址,还得再加一个目的IP,就是填充conncet的sa的IP地址

还有你的setsockopt 肯定编译不过,可能是贴错了。。

论坛徽章:
0
3 [报告]
发表于 2012-05-11 08:30 |只看该作者
你说的这些问题,我后来也发现了,但是原来这个setsockopt真心编译过了,不仅如此,我专门打印了一下返回值,是成功的。。。而且就算丢弃报文也不应该报连接超时的错误吧,我netstat监听了端口,状态为SYN_SENT,说明报文根本没发,三次握手都没成功。。。。
所以我想是不是rehel6.2对源路由还有什么特殊的设置啊。。。。

论坛徽章:
0
4 [报告]
发表于 2012-05-11 14:09 |只看该作者
本帖最后由 virusest 于 2012-05-11 14:13 编辑

我就不相信C语言认识$符号。

还有,我说你的sourceRoute的结构体有错误,少一个目的IP地址,len长度不对,按照你的填写,报文出了你本机的IP层后,中间IP地址被换成报文的目的地址,而中间路由器收到你的报文后,找不到目的地址了,因为你的这个报文是个选路报文,但是没目的IP,路由器返回一个主机不可达的icmp出错报文,所以你就收不到ACK,而你的TCP协议收到该错误后,并不立即返回给应用程序,它会尝试再发一个syn报文,大约75s后放弃,返回错误,而尝试的时间跟实现有关,这也就是connect为什么会超时,就跟服务器把网线拔了,你去connect服务器是一个道理。

如果你还是不明白,那我也无能为力了,去看看unix网络编成第23章就知道了怎么写选路程序,看看TCP/IP协议第18章第三节就知道为什么connect会超时了

论坛徽章:
0
5 [报告]
发表于 2012-05-22 20:59 |只看该作者
谢谢你的耐心回复。我按照你的提示查阅了相关资料,并将目的地址正确写入结构体,还是一样的效果,我觉得是Linux系统对源路由支持的问题。。。回复 4# virusest


   
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP