社区
网络编程
帖子详情
IOCP发送数据的小问题?
zjfhgdx
2011-09-07 08:16:12
请问对同一个socket连续调用两次wsasend,能不能保证这两次数据的发送顺序?
也就是说,是不是等第一次的数据全部发送完后才会发送第二次调用wsasend时的数据?
会不会出现,发关第一次的数据一半,然后又发送第二次的数据,然后再发送第一次的.......
请教,谢谢.
...全文
226
9
打赏
收藏
IOCP发送数据的小问题?
请问对同一个socket连续调用两次wsasend,能不能保证这两次数据的发送顺序? 也就是说,是不是等第一次的数据全部发送完后才会发送第二次调用wsasend时的数据? 会不会出现,发关第一次的数据一半,然后又发送第二次的数据,然后再发送第一次的....... 请教,谢谢.
复制链接
扫一扫
分享
转发到动态
举报
写回复
配置赞助广告
用AI写文章
9 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
xxq123321
2011-09-09
打赏
举报
回复
另外对与同一个socket连续调用两次wsasend,能不能保证这两次数据的发送顺序的问题,个人认为
1.既然wsasend是异步的,通用的做法自然是等待本次异步操作完成情况,然后进行下一次投递,
2.对于不等待wsasend异步完成就再次发送的操作(比如说在一个循环中调用wsasend)个人认为是不正确的编码方式,即你在不知道网络数据是否成功发送的基础上(套接字或其它网络环境异常)调用下一次wsasend。
3.对多次连续调用wsasend,要弄清楚系统是每次将发送数据投递到系统发送缓冲的末尾,还是直接覆盖原来缓冲,如果是前者,那系统是否有足够缓冲来应对循环调用wsasend产生的大量发送数据,如果为后者,显然多次连续调用wsasend就是明显错误的,这个楼主可以自己测试一下
zjfhgdx
2011-09-09
打赏
举报
回复
[Quote=引用 7 楼 xxq123321 的回复:]
对2楼接收数据会乱序的说法有点不同意见:
IOCP既然作为一个高性能的网络模型,显然不会吧tcp这种在网络层已经解决过的网络乱序问题再交给应用层再次重新处理,如果使用tcp协议的iocp模型时出现需要自己代码处理网络包乱序的问题,我觉得多半是代码本身的问题而不是iocp的问题,我的理解是这样的,在多线程的iocp接收中:
1.服务器把客户端socket关联iocp队列,在某个线程调用wsar……
[/Quote]
我的模型也是这样的.谢谢,你的回答.
xxq123321
2011-09-08
打赏
举报
回复
对2楼接收数据会乱序的说法有点不同意见:
IOCP既然作为一个高性能的网络模型,显然不会吧tcp这种在网络层已经解决过的网络乱序问题再交给应用层再次重新处理,如果使用tcp协议的iocp模型时出现需要自己代码处理网络包乱序的问题,我觉得多半是代码本身的问题而不是iocp的问题,我的理解是这样的,在多线程的iocp接收中:
1.服务器把客户端socket关联iocp队列,在某个线程调用wsarecv对客户端套接字投递第一次接收
2.服务去在多线程中调用GetQueuedCompletionStatus等待客户端数据到来
3.客户端发送数据给服务器
4.服务器的系统缓存中接收到数据,不管是否接收完成,GetQueuedCompletionStatus返回数据给应用层
5.这就是我和2楼不同意见的地方,GetQueuedCompletionStatus在某一个线程返回后,该线程对接收到的数据做出处理,除非此时另外有线程或其它地方对同一客户端调用wsarecv,否则不是此时是否客户端有新的发送数据上来,GetQueuedCompletionStatus都不会再次返回该客户端socket的数据,即一次wsarecv操作,只会导致一个GetQueuedCompletionStatus返回(不管是否接收到所有客户端send数据)。
6.一般情况下,线程处理完数据,再次调用wsarecv投递新的接收情况,导致下次GetQueuedCompletionStatus返回数据.
以上是我编程中采用的iocp模型处理方式,和2楼的主要不同观点是,我认为同时在多个线程中对同一个socket调用recv或其他操作引发的网络乱序或其它不可预知的问题是应用层编码本身的问题,而不是iocp的问题
zjfhgdx
2011-09-07
打赏
举报
回复
谢谢,LS大大们的回答让有对这个有了更加清晰的理解.
我的确实是多线程的.
不过我是对每个socket每接收并处理完一次数据后,才调用WSARecv的.
这样应该可以保证这个socket数据的顺序吧?也应该可能保证这个socket同时只被一个线程处理吧?
因为在一次数据处理完之前不调用WSARecv,这样也就不会接收到第二次数据了对吧??.
shenyi0106
2011-09-07
打赏
举报
回复
备注:
以上说明仅仅适用于TCP协议,UDP协议不适用
shenyi0106
2011-09-07
打赏
举报
回复
简单的说就是:对同一个socket的发送缓冲区,多线程是互斥使用的,任何要发送数据的线程,必须等待发送缓冲区中数据发送完毕,才能将自己的数据拷贝进去,否则将等待,直到原数据发送完成
shenyi0106
2011-09-07
打赏
举报
回复
不存你说的这个情况,不管是不是多线程的
可以看看MSDN上对send函数的REMARK,其中有一段是这么说的:
在调用send函数发送前,先检查发送缓冲区是否有数据正在发送,如果有,则等待发送完;
如果没有,则拷贝当前的数据到发送缓冲区,并返回拷贝的数量
lijianli9
2011-09-07
打赏
举报
回复
ls说很清楚了。关键看是否在多线程中对同一个socket进行操作。
如果操作了,就要在发送端带上包序号,然后在接收端进行组包。
jackson35296
2011-09-07
打赏
举报
回复
同一线程中连续调用两次WSASend是可以保证发送顺序的
会不会出现,发关第一次的数据一半,然后又发送第二次的数据,然后再发送第一次的.......
发送的时候不会的,TCP/IP协议保证按顺序发送两次的数据
IOCP的乱序主要发生在接收端多线程接收同一套接字的数据问题。
假如接收端有A,B,C,D共4个线程去接收这两次的数据。A线程可能接收到第一次的一半,B线程接收到第一次的另一半,C线程接收到第二次的一半,D线程接收到第二次的另一半。操作系统底层是遵守TCP/IP协议按顺序接收两次的数据,但投递到应用层之后,由于是多线程接收,就存在线程的优先级问题。在拼合这4个线程接收到的数据的时候就可能出现拼合顺序错误,就是所谓的IOCP socket乱序问题。
A线程首先接收数据这个没有问题,但是把数据投递到队列中进行拼接的时候,如果突然卡了一下(CPU刚好在给B线程分配时间片或者B线程优先级高于A线程),导致B线程后接收,但是先投递了数据。这样就导致第一次的数据拼接顺序错误。
根本原因就在于线程间时间片的切换和线程优先级不受控。
vc以
IOC
P完成端口方式实现网络数据传输
ioc
p服务器+客户端.zip
visual c++ socket
IOC
P完成端口实现网络数据传输
ioc
p服务器+客户端.zip Server端用的是同步的Accept函数
文件快速发送系统执行程序(c#版 采用
ioc
p)
每秒可以发送几十兆字节数据! 速度比飞鸽传书要快!可以测试检验! 程序开发语言为 c#,运行平台: .net 4.6。网络层采用完成端口(
ioc
p)开发。进行了多 次修改和优化,能满足大容量、高并发需求。在 socket ...
ioc
p_server_master
VS2010 完成端口 网络服务端编程 demo Copyright Alan Ning 2010 //! Distributed under the Boost Software License, Version 1.0. //! (See accompanying file LICENSE_1_0.txt or copy at
可伸缩的服务器(
ioc
p)
6.防止用户仅
发送数据
而不接收,导致服务器抛出大量发送操作 跟踪投递的发送的数量 每个struct
IOC
P_INFO中都有int nOutstandingSend;来保存发送的数量. 当投递一个发送后,nOutstandingSend++ 当发送完成后,...
完成端口(
IOC
P)高性能服务器源码
100客户 100,000(十万次)不间断的发送接收数据(发送和接收之间没有Sleep,就一个一循环,不断的发送与接收) 耗时3004.6325 秒完成 总共 10,000,000 一千万次访问 平均每分完成 199,691.6 次发送与接收 平均每秒...
网络编程
18,356
社区成员
64,214
社区内容
发帖
与我相关
我的任务
网络编程
VC/MFC 网络编程
复制链接
扫一扫
分享
社区描述
VC/MFC 网络编程
c++
c语言
开发语言
技术论坛(原bbs)
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章