---------------------------完成端口 发送完毕通知,行为的两难性

lin_style 2010-07-30 04:10:20
首先,在发包上,可分为一次性发完,和多次性。

如果是一次性发完,我不想让完成端口接到这个通知;
如果是多次性,则让完成端口接到通知,继续发剩下的。


似乎是个两难的选择,event在WSASend的时候就被确定了。
...全文
136 25 打赏 收藏 转发到动态 举报
写回复
用AI写文章
25 条回复
切换为时间正序
请发表友善的回复…
发表回复
hurryboylqs 2010-07-31
  • 打赏
  • 举报
回复
你直接用send发送就得了呗
lin_style 2010-07-31
  • 打赏
  • 举报
回复
[Quote=引用 24 楼 hurryboylqs 的回复:]

你直接用send发送就得了呗
[/Quote]

那还有什么意义? 微软对完成端口做了很多优化,不管是发送还是接收的;用send就变成同步了。对于并发连接的程序还有什么意义?
lin_style 2010-07-30
  • 打赏
  • 举报
回复
to vincent_1011
你可以控制event,达到Get是否响应这个事件。如果你不兴趣它,可以做到不在Get队列里浪费任务通知的。



看来是无解了,我也认为是操作系统的问题。操作系统应该提供个接口,如果任务一次性发完,就不要再Get中返回了。。。


明结贴。。打球累了,休息
lijianli9 2010-07-30
  • 打赏
  • 举报
回复
我觉得有IOCP的特性决定了不太可能实现。
sevencat 2010-07-30
  • 打赏
  • 举报
回复
1、如果是每次都要发很小的包,再在完成端口等返回以发下一个包,而且经常有包堵在那里需要发送,可以考虑一次性wsasend多个包(98下最多好像16个,但98以上可以很多个小包一起发送)
2、如果反正机器来得及,那就这样做未尝不可?
3、或者是把缓冲区设大一点。
来灵 2010-07-30
  • 打赏
  • 举报
回复
[Quote=引用 19 楼 vincent_1011 的回复:]
引用 17 楼 chexlong 的回复:

1,在你循环发送投递WSASend时,如果包小的话,那就一次投递成功并发送完毕
2,如果包大,首次投递可能不成功,这时就将后续的数据包依序放进发送队列,
3,步1和2投递之前,在PerIoData结构中记录下本次总共要发送的字节数
4,其实这步在1投递成功之后就立马响应到了,在完成端口工作线程捕获发送完成即opType_send中,判断已经发……
[/Quote]

完成端口基本模型是从开始创建完成端口直到服务器终止(如Windows网络编程Winsock I/O 方法一章所讲)。我这个只是发送数据的处理过程。
问题是包比较大,且发送频率高时,进行WSASend不一定成功,这时才需要将待发送数据放在发送队列,在完成端口工作线程中回调给上一层来处理,如果发送队列没数据,那么在回调中则不进行WSASend
vincent_1011 2010-07-30
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 chexlong 的回复:]

1,在你循环发送投递WSASend时,如果包小的话,那就一次投递成功并发送完毕
2,如果包大,首次投递可能不成功,这时就将后续的数据包依序放进发送队列,
3,步1和2投递之前,在PerIoData结构中记录下本次总共要发送的字节数
4,其实这步在1投递成功之后就立马响应到了,在完成端口工作线程捕获发送完成即opType_send中,判断已经发送的字节数,即GetQueuedCompleti……
[/Quote]
这个是IOCP的基本模型 ,问题楼主描述的问题好像是说如果一次发送成功的话,就不需要让GetQueuedCompletionStatus接收到这个通知。这个是相当奇怪的问题,因为如果你本来就是需要用GetQueuedCompletionStatus到来判断是不是发送发成,所以我才说这只有系统提供借口来设置才行
mscrack 2010-07-30
  • 打赏
  • 举报
回复
测过上千个连接, 不停地发送数据,
没遇到过在GetQueuedCompletionStatus返回时, 发送字节小于投递的数据大小, 请问如何测试?
来灵 2010-07-30
  • 打赏
  • 举报
回复
1,在你循环发送投递WSASend时,如果包小的话,那就一次投递成功并发送完毕
2,如果包大,首次投递可能不成功,这时就将后续的数据包依序放进发送队列,
3,步1和2投递之前,在PerIoData结构中记录下本次总共要发送的字节数
4,其实这步在1投递成功之后就立马响应到了,在完成端口工作线程捕获发送完成即opType_send中,判断已经发送的字节数,即GetQueuedCompletionStatus函数第二个参数此时返回的值,是否小于总共要发送的字节数,如果是,此时则要将总字节数减去已发送字节数,数据缓冲区指针相应移位,继续WSASend,接下来在opType_send操作即将结束时,触发已发送数据回调
5,在回调函数中要做的是,判断2中的发送队列是否存在待发送的数据,如果存在,则继续WSASend,此时同样要做3的动作,如果投递成功,则将数据从发送队列删除

就以这样的流程,应该可以。不知道描述清楚了没
vincent_1011 2010-07-30
  • 打赏
  • 举报
回复
搞不清楚,能不能一次完全发完不是需要在getxxxxstatus返回后才知道的吗?而getxxxxstatus返回不就是已经通知了吗?可能我没理解好楼主的要求。
lin_style 2010-07-30
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 vincent_1011 的回复:]

你说的这个不关MTU的事吧。MTU的处理是驱动做的,

你这个多次是不成功发送所有的数据。而这情况你根本没法控制,因为你根本不知道是不是完全发送了,除非有接口能设置如果发送成功的大小和要发送的大小不一样时候不需要置socket状态

但是又有另一个情况啊,如果你不完全发送成功的话,系统是不会帮你发的,还是要你自己再次去发送。而你却又不要收到通知,你这需求是什么情况啊?
[/Quote]
我没说MTU吧?????可能我一些细节表达有误,谅解

需求很明确啊,能一次发完,就尽量不要产生通知给上层;发不完,再产生通知给上层。别一锤子打死的设置,要不都通知,要不都不通知
vincent_1011 2010-07-30
  • 打赏
  • 举报
回复
你说的这个不关MTU的事吧。MTU的处理是驱动做的,

你这个多次是不成功发送所有的数据。而这情况你根本没法控制,因为你根本不知道是不是完全发送了,除非有接口能设置如果发送成功的大小和要发送的大小不一样时候不需要置socket状态

但是又有另一个情况啊,如果你不完全发送成功的话,系统是不会帮你发的,还是要你自己再次去发送。而你却又不要收到通知,你这需求是什么情况啊?
lin_style 2010-07-30
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 epeaktop 的回复:]

引用 6 楼 lin_style 的回复:

引用 4 楼 hurryboylqs 的回复:

有何目的?


因为很多情况下,不兴趣包发送的通知事件;除非是包过大,没发完这种情况。
要不你在发送时候在比较大的包上外带一个消息,包小的时候不加。关注吧,期待牛人给出解答
[/Quote]

这个不好。 因为包大,包小,都有可能出现发不完全的情况。
而需求的层次是,如果一次性发完,就不要通知上层。
所以我感觉两难,没法做到这样的控制层面。
只要任着发送消息通知肆虐昂贵的队列
sms88 2010-07-30
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 lin_style 的回复:]

引用 7 楼 hurryboylqs 的回复:

所以你的想法跟这个一点没冲突,事件发生对你有何影响?


起码会多占一半的事件通知队列吧。按收、发55开的话


引用 9 楼 hurryboylqs 的回复:
就算你WSASend一个很大的数据,GetQueuedCompletionStatus也有可能检测到多次的,这时候你需要调整buffer的指针和待发送数据大小来再次WS……
[/Quote]

那你试着把WSASend的倒数第二个参数设置为NULL看看
偶像罗斯福 2010-07-30
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 lin_style 的回复:]

引用 4 楼 hurryboylqs 的回复:

有何目的?


因为很多情况下,不兴趣包发送的通知事件;除非是包过大,没发完这种情况。
[/Quote]要不你在发送时候在比较大的包上外带一个消息,包小的时候不加。关注吧,期待牛人给出解答
lin_style 2010-07-30
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 hurryboylqs 的回复:]

所以你的想法跟这个一点没冲突,事件发生对你有何影响?
[/Quote]

起码会多占一半的事件通知队列吧。按收、发55开的话


[Quote=引用 9 楼 hurryboylqs 的回复:]
就算你WSASend一个很大的数据,GetQueuedCompletionStatus也有可能检测到多次的,这时候你需要调整buffer的指针和待发送数据大小来再次WSASend
[/Quote]
这个对。但是有时候包基本很小,不需要完成端口岸再来通知。

sms88 2010-07-30
  • 打赏
  • 举报
回复
就算你WSASend一个很大的数据,GetQueuedCompletionStatus也有可能检测到多次的,这时候你需要调整buffer的指针和待发送数据大小来再次WSASend
vincent_1011 2010-07-30
  • 打赏
  • 举报
回复
反正据我所知,像你这样的多次已经是在驱动层重新组包,已经对应用层完全透明了
hurryboylqs 2010-07-30
  • 打赏
  • 举报
回复
所以你的想法跟这个一点没冲突,事件发生对你有何影响?
lin_style 2010-07-30
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 hurryboylqs 的回复:]

有何目的?
[/Quote]

因为很多情况下,不兴趣包发送的通知事件;除非是包过大,没发完这种情况。
加载更多回复(5)

18,356

社区成员

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

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