我几乎总是将send()
与套接字一起使用,现在我转向WSA
函数。使用send()
,我有一个sendall()
帮助器,即使一次尝试都没有发生任何数据,并且在第一次调用时发生部分发送,它也可以确保所有数据都已传递。
因此,我决定不问您,而不是刻苦学习或在不需要时过度编写代码,而是决定:
Can a blocking
WSASend()
send partial data or does it send everything before it returns or fails? Or should I check the bytes sent vs. expected to send and keep at it until everything is delivered?
ANSWER
:重叠的WSASend()
不发送部分数据,但如果发送,则表示连接已终止。我还没有遇到过这种情况。
最佳答案
从WSASend
文档:
If the socket is non-blocking and stream-oriented, and there is not sufficient space in the transport's buffer, WSASend will return with only part of the application's buffers having been consumed. Given the same buffer situation and a blocking socket, WSASend will block until all of the application buffer contents have been consumed.
我还没有尝试过这种行为。顺便说一句,为什么您要重写代码以使用WSA功能?从标准bsd套接字api切换到基本上使用具有相同阻塞行为的套接字对我来说似乎并不是一个好主意。只需将旧的阻止代码与
send
一起保留在“重试代码”中,这样便可以移植且防弹。不保存1-2个比较就是使您的IO代码具有高性能。仅当您尝试利用Windows的某些特定优势时,或者您要使用
WSAWaitForMultipleObjects
比标准select
更好一些的非阻塞套接字时,才切换到WSA专业功能,即使在这种情况下,您也可以简单地使用send
和recv
一样。在我看来,使用带有套接字的epoll / kqueue / iocp(或将它们抽象化的库)是可行的方法。使用阻塞套接字可以完成一些非常基本的任务,但是如果您越界并且需要无阻塞的 socks ,那么直接切换到epoll / kqueue / iocp是一种方法,而不是编写痛苦的基于
select
或基于WSAWaitForMultipleObjects
的api。与基于select
的替代方案相比,epoll / kqueue / iocp不仅更好,而且更易于编程。真。它们是根据更多经验发明的更现代的api。 (尽管它们不是跨平台的,但即使选择也存在可移植性问题...)。前面提到的用于linux / bsd / windows的api基于相同的概念,但在我看来,最简单易学的是linux的epoll api。它比
select
调用要好得多,但是一旦您想到,它的编程就会容易100倍。如果您开始在Windows上使用IOCP,那我看起来会更复杂一些。如果您还没有使用过这些api,那么如果您熟悉linux,那么一定可以使用epoll,然后在Windows上使用基于类似概念的IOCP来实现相同的功能,并使用一些复杂的重叠IO编程。使用IOCP,您将有理由使用
WSASend
,因为您无法使用send
在套接字上开始重叠的IO,但可以使用WSASend
(或WriteFile
)来实现。编辑:如果要使用IOCP以获得最高性能,那么这里有一些其他提示:
关于c++ - 单缓冲区阻塞WSASend可以传递部分数据吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22821214/