http download/select timeout

Lillian123 2009-04-21 02:04:03
我的代码是从server通过http download image。 现在的问题如果同时有ftp download flow时,会出现一个问题(出现的几率为50%):
Modem(client) 不断的给server发某个pkt没有收到,通过check ACK值发现一直是等待同一个数据包的到来,server也不断的重发这个包,但是Modem好象就是没有收到,不断的发重发请求,知道select timeout后,client(Modem)主动向server发送了一个FIN终止了TCP连接,于是download失败。

我尝试着在出现select timeout的地方加了重试,而且当第一次timeout时我手动的挺调ftp flow,看是否能恢复,可是仍旧失败,也就是说,这时候停掉ftp flow仍旧会在第二次尝试select时报错。
我的select语句附下:
memset(&tv, 0, sizeof(tv));
rv = select(sock+1, &rset, NULL, NULL, &tv);

for( ; ((retry < HTTP_IO_RETRY) && (rv <=0)); retry++){
tv.tv_sec = timeout;
do {
rset = *rset_orig;
rv = select(sock+1, &rset, NULL, NULL, &tv);
/* we assume tv contains remaining time when EINTR happens */
} while (rv < 0 && errno == EINTR);

if(rv < 0) break; //if error occurs do not retry.
else if(rv == 0){
TRACE_INFO("loc_wait_for_data: select timeout! retry ... (rv = %d , retry = %d)",rv,retry);
continue;
}
}

请教高手指点。 高分结贴
...全文
188 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
once_and_again 2009-05-27
  • 打赏
  • 举报
回复

http传送的是数据报 ?
Lillian123 2009-05-27
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 morris88 的回复:]
引用 10 楼 Lillian123 的回复:
morris88:
1、server 发送,但 client 没有收到。看看发送的地址对不对?client 用 wireshark 能抓到 server 发来的包吗?
2、client 发送 fin 终止 tcp 连接,就是与 server 就是断开了某个方向的连接;client 不重建连接,那就是你的处理问题了,如果还要
同 server 通信,就必须重新建立连接


我想我没有表达清楚我的意思,ok,let me explain it :
1. 我所说的(通过wireshark抓包看到有重发) -- 就是指从client端抓到的报文。
2. client发送了FIN是由于我的select timeout后,我的代码里主动close的连接。我说client没有重新建立连接 -- 是为了回答你上次的回答:我是想说明在发生timeout之前是用的同一个socket。


tcp 位于 socket 层之下,并且由 tcp 协议层自动管理如连接建立、数据可靠传输、重传、连接断开等,
位于其上的 tcp socket 是控制不到其下面的 tcp 协议层的具体处理的;貌似对方断开后重新建立连接
后,其 socket 不一定就是上次的那个 socket,上次那个 socket 在对端断开连接时已经被销毁了,你不应该
再用上次的 socket...

morris88 2009-05-05
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 Lillian123 的回复:]
morris88:
select timeout是由于socket没有收到数据,但是server实际上是将包发送出去了(通过wireshark抓包看到有重发)。
而且看到是client端由于select timeout后,主动发送了一个FIN来终止的tcp连接。也就是说server没有断开,client也没有重新建立连接的过程。
[/Quote]

1、server 发送,但 client 没有收到。看看发送的地址对不对?client 用 wireshark 能抓到 server 发来的包吗?
2、client 发送 fin 终止 tcp 连接,就是与 server 就是断开了某个方向的连接;client 不重建连接,那就是你的处理问题了,如果还要
同 server 通信,就必须重新建立连接

建议你看看《TCP/IP详解》卷 1 吧...
Lillian123 2009-05-05
  • 打赏
  • 举报
回复
same error.郁闷! 还没有找到原因...
Lillian123 2009-05-05
  • 打赏
  • 举报
回复
morris88:
select timeout是由于socket没有收到数据,但是server实际上是将包发送出去了(通过wireshark抓包看到有重发)。
而且看到是client端由于select timeout后,主动发送了一个FIN来终止的tcp连接。也就是说server没有断开,client也没有重新建立连接的过程。


linqzly:

OK,我会试试的。
morris88 2009-04-23
  • 打赏
  • 举报
回复
tcp 位于 socket 层之下,并且由 tcp 协议层自动管理如连接建立、数据可靠传输、重传、连接断开等,
位于其上的 tcp socket 是控制不到其下面的 tcp 协议层的具体处理的;貌似对方断开后重新建立连接
后,其 socket 不一定就是上次的那个 socket,上次那个 socket 在对端断开连接时已经被销毁了,你不应该
再用上次的 socket...
morris88 2009-04-23
  • 打赏
  • 举报
回复
这个貌似有极大的安全漏洞哦,不知道解决没有哈...

一般都是:用php读取文件再发送出去

Header("Content-Type: XXXXXXXX");
readfile(文件路径);
eyun221 2009-04-22
  • 打赏
  • 举报
回复
up............
linqzly 2009-04-22
  • 打赏
  • 举报
回复
这是要放在循环里面的,FD_SET宏是把fd_set结构的相应位设置起来,当使用select的时候,如果有被设置的fd有读或写的时候,fd_set那一位就会发生变化,表示当前对应的fd可读或可写。所以这样每一次使用select之前都要重新FD_SET一下。


ps: 我还有另外一个问题,只有 morris88 回复了,希望有高手能帮忙看看。谢谢了。

主要是想知道: chunked http 是需要设置http server的配置文件来支持? 还是client发送request时带上
“ transfercoding : chunked”?


回复:
一般http server都支持的, 格式应该是这样的,具体的可以查一查rfc文档
...\r\n
transfercoding: chunked\r\n
...\r\n\r\n

chunked size\r\n
data\r\n
chunked size\r\n
data\r\n
....
Lillian123 2009-04-21
  • 打赏
  • 举报
回复
回答hairetz:
因为daemon是用来download image 从http server。 所以daemon是作为client发送一个请求报文,server会不断的发送data过来,当网络拥有丢包现象时,client通过发ACK序列号来通知server该报没有收到,于是server会重发该报文。

linqzly:

你的代码和我的区别就在于:
FD_ZERO(&rest);
FD_SET(sock, &rest);
这两个会在循环内。
曾在论坛上看到有说要把这个放到循环内的,但是我个人认为只需把timeout value重新赋值。 没有必要把这两句放到循环内。如果你觉得必须,可以告诉我原因吗?

谢谢各位回复。


ps: 我还有另外一个问题,只有 morris88 回复了,希望有高手能帮忙看看。谢谢了。

主要是想知道: chunked http 是需要设置http server的配置文件来支持? 还是client发送request时带上
“ transfercoding : chunked”?

linqzly 2009-04-21
  • 打赏
  • 举报
回复
fd_set rest;
again:
FD_ZERO(&rest);
FD_SET(sock, &rest);
memset(&tv, 0, sizeof(tv));
tv.tv_sec = timeout;
rv = select(sock+1, &rset, NULL, NULL, &tv); //rset是否赋值?

if (rv < 0)
{
return -1;
}
if (rv == 0) //timeout
{
goto again;
}
read(sock,....);
  • 打赏
  • 举报
回复
为何会一直没有收到包呢?这个时候tcp连接建立起来了没有?等待一个什么包?
Lillian123 2009-04-21
  • 打赏
  • 举报
回复
没错! 是好象client端没有收到包,至少socket层没有收到,奇怪的现象。
morris88 2009-04-21
  • 打赏
  • 举报
回复
[Quote=引用楼主 Lillian123 的帖子:]
Modem(client) 不断的给server发某个pkt没有收到,通过check ACK值发现一直是等待同一个数据包的到来,server也不断的重发这个包,但是Modem好象就是没有收到,不断的发重发请求,知道select timeout后,client(Modem)主动向server发送了一个FIN终止了TCP连接,于是download失败。 [/Quote]

这个是由 tcp 协议自己管理、控制的,它上面的应用是没有办法来恢复的...
貌似原因在于 client 没有收到 server 发送的某个 seq 的包啊...
查查为什么没有收到吧...

23,120

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧