关于FD_WRITE 10035 10053 请大侠指教,跪等。

hehaheha 2007-09-10 02:36:12
做个局域网多文件传输应用,使用socket api 事件模式,现在出现的问题是发送文件有时成功有时失败,失败通过WSAGetLastError()取得错误号为10035,通过查找资料在发送出现10035时等待FD_WRITE,然后将上一个send失败的数据再次发送,循环若干次后由出现10053错误,含义是连接以放弃或超时,设置了超时时间还是一样。
希望哪位大侠给个使用fd_write的程序流程结构,或避免出现10035的方法。
注:我使用的是非阻塞socket.
...全文
550 20 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
alfwolf 2007-09-11
  • 打赏
  • 举报
回复
楼主,你可以找找<Windows网络编程>这本书,第8章介绍了异步模式下的各种winsock I/O模型,里面也详细谈到了应对WSAEWOULDBLOCK的方法.
如果你找不到,我可以将这章的电子书发给你.
arong1234 2007-09-11
  • 打赏
  • 举报
回复
下面代码是在abuse你得系统资源,不要总用循环解决你问题。你不是有WSASelectEvent么?为什么要循环?
if(sendcnt == WSAEWOULDBLOCK)
{
Sleep(1);
//这里应加循环次数控制判断,即设置超时,跳出循环
//...
continue;
}
arong1234 2007-09-11
  • 打赏
  • 举报
回复
楼主一定要明白10035不是错误,这是正常情况。只是当时网络没有数据,还得等
hehaheha 2007-09-11
  • 打赏
  • 举报
回复
也就是我现在recv出现了10035错误,我可以等待FD_READ事件后再次recv直到成功?
alfwolf 2007-09-11
  • 打赏
  • 举报
回复
我给你一个10035错误的常见含义,请仔细考虑你设计方面是否存在问题.

WSAAccept和accept
应用程序没有收到连接请求。再次调用,便可检查连接情况

closesocket
大多数情况下,这个错误意味着已随SO_LINGER选项一道,调用了setsockopt,而且已设定了一个非零的超时值

WSAConnect和connect
应用程序已初始化。再次调用,便可检查是否完成

WSARecv、recv、WSARecvFrom和recvfrom
没有收到数据。稍后再次检查

WSASend、send、WSASend To和sendto
外出数据无缓冲区可用。稍后再试
hehaheha 2007-09-11
  • 打赏
  • 举报
回复
用的WSAEventSelect模型

WSAWaitForMultipleEvents等待事件发生
hehaheha 2007-09-11
  • 打赏
  • 举报
回复
使用的select模型啊。
alfwolf 2007-09-11
  • 打赏
  • 举报
回复
对于异步的通讯模式,你是不断得重复调用某函数如recv呢?还是使用了如select这样的I/O模型?
hehaheha 2007-09-11
  • 打赏
  • 举报
回复
客户端和服务端都是我写的,接收端没有做什么特殊的操作,仅仅就是接受接收数据写入文件。

调试发现每次发送4096字节,服务器端能正常发送5个左右4096字节和客户端能够接受大概5次4096字节后接收端出现10035错误,何解?
hehaheha 2007-09-11
  • 打赏
  • 举报
回复
wsaselectevent 事件为FD_CLOSE FD_READ FD_WRITE
在发生10035错误后
WaitForMultipleObjects
分析具体事件对象,确实有FD_WRITE事件被触发。有什么问题吗?
arong1234 2007-09-11
  • 打赏
  • 举报
回复
to:wfenj(小芬)

alfwolf(木马煞)

和对方有关是没错,但是你从编程角度讲是关心不了的,这个应该是接收方,也就是对方应该关心的。如果本方发送的数据合法,对方因为他缓冲出问题,则这是对方的错误,不是你的。本端无法控制、确保对方也正确。这时候如果要考虑对方,就应该问的是:对方设计的对不对?
arong1234 2007-09-11
  • 打赏
  • 举报
回复
10053肯定和对方或者防火墙有关,但是不会具体到诸如对方接收缓冲的问题。对方的缓存等实现细节不需要发送方考虑,只要你发送的数据“合法”即可

至于收到10035之后Sleep(1)然后再尝试,这是非常不好的一种设计,这等于在滥用你的CPU资源。合理的方法是用select函数等待socket可写,或者等待窗口返回FD_WRITE,我不确信你所谓的检测FD_WRITE是啥意思?FD_WRITE可以等待么?如果你是用overlapped事件模型应该可以

至于10053,单纯从你这方是看不出的,要同时研究对方的行为。当你确信对方肯定没问题时再从你这里下手。

对于这种问题,恐怕你要用抓包软件看看你自己收发的包到底有没有问题,单纯从代码看不出来的
ringphone 2007-09-11
  • 打赏
  • 举报
回复
发送cnt字节数据:
do
{
sendcnt = send(sock,buf,cnt,MSG_DONTROUTE);
if(sendcnt == SOCKET_ERROR)
{
sendcnt = WSAGetLastError();
if(sendcnt == WSAEWOULDBLOCK)
{
Sleep(1);
//这里应加循环次数控制判断,即设置超时,跳出循环
//...
continue;
}
else
{
//发送数据数据失败
break;
}
}
cnt -= sendcnt;
buf += sendcnt;
}while(cnt > 0);
hehaheha 2007-09-11
  • 打赏
  • 举报
回复
上面有点错误,再次发送后忘了
ErrCode = WSAGetLastError();
if(ErrCode==0) break;

收到FD_WRITE消息后
WSAEVENT 变量我也reset了。
hehaheha 2007-09-11
  • 打赏
  • 举报
回复
谢谢各位回答,我的大致流程是这样的
while(flag)
{
///读文件
///发送读取的缓存,按windows 默认的8k ,我有个程序16k也没问题,各种大小我也试了。
if(发送返回SOCKET_ERROR)
{
int ErrCode = WSAGetLastError();
while(ErrCode==10035)
{
waitforsingleobject //FD_WRITE,这里确实收到了FD_WRITE消息
///再次发送上面的缓存 /////再次发送时出现了10053错误,可能是连接断开,也可能是发送超时,设置了超时时间问题依旧。
if(发送成功) break;
else
continue;
}
}

}

大致流程就这样,不知道错在什么地方,望大侠指教
hehaheha 2007-09-11
  • 打赏
  • 举报
回复
终于搞定了,但是发现用这种模式做个文件夹传输的状态控制太多了,不知道各位有什么好的方法推荐。结贴,再次感谢各位。
wfenj 2007-09-10
  • 打赏
  • 举报
回复
应该和对方有关系的,应该是TCP连接的话对方要有响应把
arong1234 2007-09-10
  • 打赏
  • 举报
回复
这种错误和对方接收缓冲有啥关系?
alfwolf 2007-09-10
  • 打赏
  • 举报
回复
请注意另一端的接收缓冲
arong1234 2007-09-10
  • 打赏
  • 举报
回复
10035不是失败,这是预期的错误,如果遇到10035,你应该过一会再重试,正确的方法是通过select检查socket的可写性,等可写再send
至于10053,应该是对方关闭链接

我想你至少得弄明白WSAEWOULDBLOCK得含义再说

至于流程,我想应该是不停发送,直到下面几个条件中有一个出现

1. 没有数据需要发送
2. 收到新得WSAEWOULDBLOCK(10035)
3. 其他错误

对于1. 则等待你新得要发送数据
对于2. 放弃当前发送,等待新得FD_WRITE
对于3. 你应该立刻关闭socket

18,363

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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