异步发送 10035

rnon637 2009-01-15 01:29:54
我用WSAEventSelect模式
服务器一直给客户端发送数据
	char temp[256] = {0};
memset(temp, 10, 256);
for (int j=0;j<1000; j++)
{
int nSend = ::send(sockArray[i], temp, strlen(temp), 0);
if (nSend < 0)
{
int nError = GetLastError();
printf("send Error!-- %d\n", nError);
}
else
{
printf("%d------\n", (j+1));
}
}

一直发送 有的时候就会发不成功。提示10035错误 如果出现这个错误而一直让它重发的话 那一个10M的文件都要发很久
大家有没有好的提议呀 该怎么处理才能速度快点呢
...全文
611 24 打赏 收藏 转发到动态 举报
写回复
用AI写文章
24 条回复
切换为时间正序
请发表友善的回复…
发表回复
rnon637 2009-01-20
  • 打赏
  • 举报
回复
呵呵 现在就是要处理这个问题 不是说不行就不行 应该想个问题来解决的
多个连接的话 这个很不可取
我用完成端口 没出现过这个问题
不过这个模式 没怎么用
ProgrameMan 2009-01-20
  • 打赏
  • 举报
回复
to 楼主:

完成端口不存在这个问题是因为操作系统内部对待发送的数据进行了缓存,也就是说如果TCP的发送缓冲区已满则,操作系统会将你要发送的数据加入待发送队列当检测到发送缓存区中有空闲的时候在进行发送。这也就是为什么在进行完成端口的发送时数据往往需要从堆上分配而不是栈上分配的具体原因。所以单纯从吞吐量的角度来看完成端口不一定比 select + 非阻塞套接字的方式更高。
ProgrameMan 2009-01-18
  • 打赏
  • 举报
回复
to rnon637:

可是等就要花费时间了 我一直发 就是当变可写的时候才能继续发 可是时间就变长了

这是正常的,因为网络的传输速度远远小于计算机的允许速度,你可以通过建立多个连接将待发送数据分段发送这样的话速度会有一定的提升,但是要注意到一点是当连接达到一定数量后网络带宽将会成为新的瓶颈。
rnon637 2009-01-18
  • 打赏
  • 举报
回复
[Quote=引用 20 楼 ProgrameMan 的回复:]
非阻塞的套接字发送出现 10035 后可以通过使用 select 来探测套接字上是否可写,当套接字再次变为可写时在发送数据即可。
[/Quote]
可是等就要花费时间了 我一直发 就是当变可写的时候才能继续发 可是时间就变长了
tan_storm2000 2009-01-17
  • 打赏
  • 举报
回复
楼上说的其实都没说到关键
楼主这样发送大文件的方法根本不是正确的方法,因为这样根本没有考虑发送缓存是否已经满了或网络的异常状况,
这样一直发一直发,完全不考虑结果,只要有一个send没发送成功,那么本次文件发送就会失败,在实际应用中根本不可取;
楼主的做发是一种理想的做法;

如果非要这样循环读\循环send的话,可以在每次循环的时候Sleep(10)一下,这样基本就没有问题,但不推荐这样做,这样会
使程序效率极其低效;

要做好大文件的发送,要考虑以下几个方面:
1, 发送缓存的选取
2, 文件的读取,可以考虑使用内存文件,如果能够一次性读取的话,就不要读那么多次,总之就是要减少读取的次数
* 由于Tcp/ip协议能够自己进行流量控制,所以即使你在发送的时候一次将整个文件一次发送,也不会有问题
* send的时候没必要每次只发送一点点数据,太影响效率了,一个文件要发送很久才能传完


百事烟 2009-01-17
  • 打赏
  • 举报
回复
10035出错的原因是这样的
因为你采用了WSAEventSelect,这个函数会自动把socket设成了非阻塞模式。
非阻塞模式的socket在send前一定要检查socket的当前状态是否为可send状态,因为你没有合理的检查机制,导至在socket不可send的状态你send了。
阻塞模式的socket在send的时候不用检查状态的,可以直接send.

阻塞模式 写法简单,适合单连接。
用阻塞模式写多连接也可以,不过有几个连接,就得最少开几个线程,为方便控制,书上推荐开连接数*2个线程。

非阻塞模式,相当难控制,对于现在的我来说,是个很大的工程,正在学习中...
如果有多个连接,书上建议用非阻塞模式,因为不管有多个连接,只要1-2个线程就可以搞定。

非阻塞模式有5种控制方法如下(抄书):
1.select模型
2.WSAAsyncSelect
3.WSAEventSelect
4.重叠模型
5.完成端口模型

你采用的是第3种。

我QQ41184836,互相交流



百事烟 2009-01-17
  • 打赏
  • 举报
回复
楼主,我回去看了一下书,我说的都是错的,对不起,,
源码在http://download.csdn.net/down/369031/dlyhlq
第7,8章,这个保证是对的,我正在学习
ProgrameMan 2009-01-17
  • 打赏
  • 举报
回复
非阻塞的套接字发送出现 10035 后可以通过使用 select 来探测套接字上是否可写,当套接字再次变为可写时在发送数据即可。
tan_storm2000 2009-01-17
  • 打赏
  • 举报
回复
楼上的,你没明白我的意思
姑且不论Sleep(1)是为了防止CPU 100%,还是防出错,这无关紧要,
一个合理高效的服务器是不会这样发送数据的;

大文件100%是要拆的,毫无疑问
一般的小文件,又能占多少内存呢!为什么不能一次读完?
我想说的是,每次"尽量"多从文件读些数据进来,避免频繁读写磁盘,象这样的代码是没有任何问题的:
int ret = fread( bug, sizeof(char) , 65536, pFile);
int nsend = send(mSock,(char *)bug, ret, 0);
百事烟 2009-01-17
  • 打赏
  • 举报
回复
楼上的,
可以在每次循环的时候Sleep(10)一下,这样基本就没有问题
//Sleep(1000)该出问题还是会出问题,但通常加上Sleep(1),这样为防止CPU 100%,而不是防出错

我搞不明白,把文件拆开(只要不拆成1bit),有什么不妥 1040-10240之间都可以运行的很好
发整个文件,一个文件4M的话,就是4M内存,机器只运行你一个程序?
scq2099yt 2009-01-16
  • 打赏
  • 举报
回复
把你放读取文件的缓冲区加大点。
百事烟 2009-01-16
  • 打赏
  • 举报
回复
补充一下,可以异步发送(即在线程中发,在线程中可选发消息以确认发送状态),但socket一定要设成阻塞模式。
socket默认是阻塞模式的,但用WSAEventSelect方式会把监听到的socket自动设成非阻塞模式,你监听到以后手动把它改为阻塞模式就可以发送(send)了
闪破风浪 2009-01-16
  • 打赏
  • 举报
回复
注意内存拷贝后的处理~
百事烟 2009-01-16
  • 打赏
  • 举报
回复
TCP情况下:
负责监听和接收的socket:可以采用非阻塞;
负责发送的发送的socket要采用阻塞模式;

因为TCP协议在网络上传输的两端是阻塞传输的,你在代码中设置非阻塞只是要socket把数据放到本地缓冲区上就不要管了,其实数据还在本地缓冲区,在上次发出去的数据没有得到回应以前,数据将一直不会发出去,但这时你的socket又把下一批数据放入缓冲区,

在本机上,把发送端的包大小设置为10240,接收的包设置为5120,会立即出错。

解决办法:
1.TCP情况下,把负责发送的socket采用阻塞模式;
2.采用UDP
rnon637 2009-01-16
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 Delphigis 的回复:]
补充一下,可以异步发送(即在线程中发,在线程中可选发消息以确认发送状态),但socket一定要设成阻塞模式。
socket默认是阻塞模式的,但用WSAEventSelect方式会把监听到的socket自动设成非阻塞模式,你监听到以后手动把它改为阻塞模式就可以发送(send)了
[/Quote]
有点晕晕的,不怎么懂。能弄个小DEMO给我看下吗?我的邮箱sb1250@163.com
xyj0663 2009-01-15
  • 打赏
  • 举报
回复
加大些,每次搞个1K看看
lijianli9 2009-01-15
  • 打赏
  • 举报
回复
把你放读取文件的缓冲区加大点。
oyljerry 2009-01-15
  • 打赏
  • 举报
回复
把temp的空间加大一点,1500个字节等 每次多发送一点数据
rnon637 2009-01-15
  • 打赏
  • 举报
回复
10035错误的原因是无法立即完成一个非阻挡性套接字操作。
原因就说缓冲区满了 所以无法立即
jyh_baoding 2009-01-15
  • 打赏
  • 举报
回复
查一下10035的错误原因
加载更多回复(4)

18,364

社区成员

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

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