社区
网络编程
帖子详情
IOCP服务器有很大量数据分成很多包发送,在GetQue线程中投递WSAsend发送,得到结果等于发送数继续发下一条,老是丢数据,请问如何确保发
sdf123321
2006-04-19 10:53:48
如题!!!,请教高手
...全文
565
20
打赏
收藏
IOCP服务器有很大量数据分成很多包发送,在GetQue线程中投递WSAsend发送,得到结果等于发送数继续发下一条,老是丢数据,请问如何确保发
如题!!!,请教高手
复制链接
扫一扫
分享
转发到动态
举报
AI
作业
写回复
配置赞助广告
用AI写文章
20 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
ifeelhappy
2006-09-06
打赏
举报
回复
我把流程说一下,各位老大分析一下:
客户端采用Csocket OnRecice后recv到信息直接写文件,不做其它事情。
服务器端:线程A检测有没有发往客户端的信息,有的话就产生信息写入发送缓冲区a,判断该客户端SOCKET是否正在发送,如没有发送就PostQueuedCompletionStatus(m_hiocp, 0, (DWORD)lpmyio, &lpmyio->pSIOContext->ol); 通知完成端口开始发送数据。
完成端口GetQue返回后就检测发送缓冲区a有没有等待发送的数据,有就取得数据投递WSASend发送,等下次GetQue返回时候判断发送字节是否等于需要发送数据,如确认相等后就继续从发送缓冲区a取下一条投递WSASend发送。
如此循环,单步跟踪,发送10次数据都正常,单正常运行时候,发送2次后在WSASend时候就有WSA_IO_PENDING发生,看了WSASend参数dwBytes的值是一个很大的数,按常理说GetQue完成了才发下一条,系统缓冲不应该还有数据呀,不应该出现WSASend呀,请高手解答。
-----------------------------------------------------------------------------------
我是菜鸟,我来说一下,你看看我的意思.
你发送了,只是说你告诉系统去做这样一个IO操作,系统知道了之后,不一定立刻去做,但是他一定会去做,做完之后还会通知你做完了.这就是完成端口的作用.你发送了之后去看缓冲区肯定是有数据的,而且肯定会经常那个WSA_IO_PENDING错误的.这有什么不对呢?
萧山夜雨
2006-06-22
打赏
举报
回复
硬撑者,这名字好有意思啊。
萧山夜雨
2006-06-22
打赏
举报
回复
这个问题我以前也碰过,
客户端使用delphi的CClientSocket异步方式接完成端口的包时,老是丢,或数据不完整,累计发送 != 累计接收数,后来我使用ClientSocket阻塞方式,就不丢了,但是慢。
再后来试了一下,vc的CSocket用异步方式也不丢数据,并且速度快。6000包,不到1秒就传完了。
CPP2008
2006-06-22
打赏
举报
回复
一定是你代码的问题。
仔细的调试下。
10个包一组,10个包一组的调试。
把服务器的发送流程print出来,自然就清楚了。
sdf123321
2006-04-20
打赏
举报
回复
我把流程说一下,各位老大分析一下:
客户端采用Csocket OnRecice后recv到信息直接写文件,不做其它事情。
服务器端:线程A检测有没有发往客户端的信息,有的话就产生信息写入发送缓冲区a,判断该客户端SOCKET是否正在发送,如没有发送就PostQueuedCompletionStatus(m_hiocp, 0, (DWORD)lpmyio, &lpmyio->pSIOContext->ol); 通知完成端口开始发送数据。
完成端口GetQue返回后就检测发送缓冲区a有没有等待发送的数据,有就取得数据投递WSASend发送,等下次GetQue返回时候判断发送字节是否等于需要发送数据,如确认相等后就继续从发送缓冲区a取下一条投递WSASend发送。
如此循环,单步跟踪,发送10次数据都正常,单正常运行时候,发送2次后在WSASend时候就有WSA_IO_PENDING发生,看了WSASend参数dwBytes的值是一个很大的数,按常理说GetQue完成了才发下一条,系统缓冲不应该还有数据呀,不应该出现WSASend呀,请高手解答。
sdf123321
2006-04-19
打赏
举报
回复
另外我调用WSAsend时,有时候会返回WSAGetLastError() = WSA_IO_PENDING 的阻塞错误,并且WSAsend返回的发送字节数dwSendNumBytes为随机值,我投递WSAsend是在上一个GetQue返回后才投递的呀,怎么还会有WSA_IO_PENDING错误,难道GetQue返回了发送字节数等于wsasend的发送字节数的时候,SOCKET的系统发送缓冲还没有发送完?怎么还会阻塞,不应该呀?郁闷!!
sdf123321
2006-04-19
打赏
举报
回复
我用telnet测试的
gohappy_1999
2006-04-19
打赏
举报
回复
接收端的问题吧
sdf123321
2006-04-19
打赏
举报
回复
在线等待!!!在线结贴!!!
sdf123321
2006-04-19
打赏
举报
回复
TO:striking(硬撑者):
服务器端分10000个包,每个包都有编号,在GetQue线程中投递WSAsend发送,在GetQue中得到发送字节数等于发送数,继续投递下一个WSAsend发送,依次循环,全部发送完后,结果客户端收到的全部数据小于服务器发送的数据?不知流程是否有问题,请指点,谢谢!!
striking
2006-04-19
打赏
举报
回复
描述不够清楚.
老是丢数据: 你指的是发送的时候丢数据,还是客户端接收的时候数据不完整.
tcp发送不会丢数据的. 代码问题大.
sdf123321
2006-04-19
打赏
举报
回复
可就是查不出问题
sdf123321
2006-04-19
打赏
举报
回复
有道理
pripor
2006-04-19
打赏
举报
回复
这种情况丢包
一般是程序本身的问题
fengge8ylf
2006-04-19
打赏
举报
回复
按楼主说的很合理啊 不应该丢包 是不是接收端的问题 接收用一个死循环来接收
striking
2006-04-19
打赏
举报
回复
-_-!!!
sdf123321
2006-04-19
打赏
举报
回复
我是比较了呀,这些都没有问题,关键是我比较后,继续投递下一个WSASend的时候,怎么还会返回WSA_IO_PENDING呢?按理说这时候系统发送缓冲中应该都处理完了呀?
striking
2006-04-19
打赏
举报
回复
那个不叫阻塞, 有时候网络原因, 发出1000个字节, 不是一下子就能全部发出去的,
所以会返回WSA_IO_PENDING (未决), 表示目前系统正在发送数据.
当收到通知后, 根据dwSendNumBytes来判断此次发了多少字节, 比较一下, 剩下未发出去的, 再投递一次. 把剩余的发出去.
sdf123321
2006-04-19
打赏
举报
回复
我是这样呀,我是通过GetQue的参数dwSendNumBytes和WsaSend的发送字节数相同,说明全部发送完毕,才投递下一个WsaSend的,而且只是投递一个WsaSend,这时候WSAsend怎么还会阻塞呢?
striking
2006-04-19
打赏
举报
回复
WSAsend是一种重叠操作, 一般调用是立即返回, 当返回0 表示发送成功, 否则如果返回WSA_IO_PENDING 表示这时候系统正在发送数据, 那么你需要通过GetQue来获得此次发送的结果,
到底是发送了几个字节(通过GetQue的参数dwSendNumBytes获知.)
windows下高效网络通讯
IOC
P
对
IOC
P做了很好的处理,良好的通讯机制和SOCKET io的预分配和预
投递
机制
自己写的
IOC
P源代码
自己写的
IOC
P源代码,可重用。用时标明出处即可。 一个连接同一时刻仅有一个待处理的接收
投递
。
IOC
P模型总结
IOC
P模型总结
IOC
P模型总结
IOC
P模型总结
IOC
P模型总结
IOC
P模型总结
IOC
P模型总结
IOC
P模型总结
IOC
P模型总结
代码客:G-Socket(
IOC
P) 1.0 (Server/Client)例程源码+Server体验程序+强大的压力测试工具
结构层次及相互联系 (1)、工作
线程
:响应连接的IO
投递
返回并负责
投递
读请求,并将IO返回结果
投递
给处理
线程
,可设定参
数
决定工作
线程
数
量; (2)、处理
线程
:处理
线程
调用回调函
数
将信息传递给应用层或协议栈,可设定参
数
决定工作处理
数
量; (3)、看守
线程
:响应Accept事件调用AcceptEx,检测连接和心跳超时 ,将信息
投递
给工作
线程
,模块仅有一个看守
线程
。 1. 技术要求 (1)、
线程
同步:Lock指令、临界段; (2)、主要Socket API:W
SAS
end
、WSARecv、AcceptEx、DisconnectEx; (3)、内存管理:连接池(句柄重用)、内存池; (4)、
数
据
0拷贝:通过内置处理
线程
,上层应用可以避免自建
线程
池及复制
数
据
的过程。同时提供GBuf内存分配功能,应用层获得分配地址及填充
数
据
之后亦可直接
投递
给内核/驱动层; (5)、
数
据
顺序同步:同一个连接同时只有一个处理
线程
响应其IO事件; (6)、IO请求
投递
:单
投递
读、多
投递
写; (7)、0缓冲读
投递
:可条件编译实现,以适用大规模连接要求。 (8)、超时机制:可设置空连接(连接不
发
送
数
据
)超时时间以防止DOS攻击,也可设置心跳超时时间防止网络故障导致的现有连接成为虚连接避免耗尽系统资源。 (9)、接口技术:API、回调函
数
、客户句柄(客户连接句柄)。 (10)、主、被动
发
送
:不使用HASH、MAP及LIST技术,即可提供安全可靠高效的客户连接句柄,以实现
服务器
端主被动
发
送
数
据
功能; (11)、PerHandleData的回收不以IO
投递
的计
数
器或链表来做依据但仍能安全回收,同时尽量避免在高频的读写操作时做其他无关的操作以提高读写效率。 (12)、处理
线程
和工作
线程
有着良好分工界限,繁重的工作交给处理
线程
完成,工作
线程
工作量最大限度的减少,仅响应
投递
返回及读
投递
的操作; (13)、支持AWE,模块自动识别AWE是否开启(需手动开启),“否”则使用虚拟内存机制。 2. 功能要求 (1)、多IP多端口监听,每个监听可设置不同的回调函
数
,以高效的区别处理
数
据
(2)、可设置每秒最大的连接并
发
量和空连接(连接不
发
数
据
)超时时间以防止DOS攻击造成的服务瘫痪、具有心跳处理(防网络异常造成的虚连接)功能 (3)、不加协议的透明传输,可适用广泛的网络通讯环境 (4)、可现实主、被动
发
送
数
据
,但不会因兼顾主动
发
送
而额外增加降低效率的工作 (5)、内置处理
线程
,上层应用可不必自建
线程
池处理
数
据
,所有IO事件按顺序调用回调函
数
并可以在回调函
数
内直接处理
数
据
,不必担心多
线程
造成的接收
数
据
乱序的问题。 (6)、高效率的
数
据
对应关联机制,在初次连接并根据登录
数
据
设置每个连接对应的宿主(Owner)之后,再接收的
数
据
即可立即获得该连接对应的宿主,而不必再做额外的查询工作,并且模块内部采用的是指针关联方式,对于长连接、主动
发
送
的
服务器
系统而言是高效率的。 (7)、可兼容IPv6 3. 注意事项 因硬件环境和应用环境不同,不合理的配置会出现效率及性能上的问题,因此以下情况出现时,请务必与作者联系以
确保
获得更好的参
数
配置: (1)、连接量超过1000个的。超过的应结合具体硬件配置和网络带宽等因素综合设定运行参
数
。 (2)、带宽使用率超过20%的。工作
线程
和处理
线程
数
量的设置也是综合考虑
数
据
吞吐量和
数
据
处理负载的因素来设置的,过多的
线程
会在调度上浪费时间,同时也应该综合考虑
线程
优先级别来设置工作
线程
和处理
线程
数
量,两者的设置也不一定能相等。 (3)、
服务器
端有主动
发
送
需求的、短连接(含网络故障造成的连接断开)出现频率高的。 压力测试工具介绍: 一、 使用G-TcpClient模块 二、 可以设定间隔时间
发
起大规模长、短连接 三、 可以
发
起密集
数
据
包
,
包
括即时和定时
发
送
,1M的光纤带宽最大可以达到100K/S(单向)以上,100M本地网最大可以达到10M/S(单向)以上 四、
数
据
发
送
仅由一个独立
线程
但当,每点击一次Connect就创建一个
线程
根据当前参
数
发
起连接。 五、 测试前提:
服务器
接收客户端
数
据
后立即原样返回给客户端
WinSock完成端口IO模型.pdf
WinSock完成端口IO模型.pdf
网络编程
18,358
社区成员
64,186
社区内容
发帖
与我相关
我的任务
网络编程
VC/MFC 网络编程
复制链接
扫一扫
分享
社区描述
VC/MFC 网络编程
c++
c语言
开发语言
技术论坛(原bbs)
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章