在完成端口中调用WSASend()? [英] Calling WSASend() in completion port?

查看:845
本文介绍了在完成端口中调用WSASend()?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

你们中的很多人知道原来的send()不会写入你要求的字节数。

Many of you know the original "send()" will not write to the wire the amount of bytes you ask it to. Easily you can use a pointer and a loop to make sure your data is all sent.

但是,我看不到在WSASend()和完成端口是如何工作的这个案例。它立即返回,并且您无法控制发送了多少(除了在例程中可以访问的lpLength)。这是如何解决的?

However, I don't see how in WSASend() and completion ports work in this case. It returns immediately and you have no control over how much was sent (except in a lpLength which you have access in the routine). How does this get solved?

你必须多次调用WSASend(),以获得所有的数据?这不是一个很大的缺点,特别是如果你想要你的数据以特定的顺序出现,并且多个线程访问例程?

Do you have to call WSASend() in the routine multiple times in order the get all the data out? Doesn't this seem like a great disadvantage, especially if you want your data out in a particular order and multiple threads access the routines?

推荐答案

当使用与 IOCP 相关联的套接字调用 WSASend OVERLAPPED 结构,您可以有效地将数据传递到网络堆栈发送。一旦您使用的数据缓冲区不再需要网络堆栈,网络堆栈将给您一个完成。此时,您可以自由地重复使用或释放​​用于数据缓冲区的内存。

When you call WSASend with a socket that is associated with an IOCP and an OVERLAPPED structure you effectively pass off your data to the network stack to send. The network stack will give you a "completion" once the data buffer that you used is no longer required by the network stack. At that point you are free to reuse or release the memory used for your data buffer.

请注意,数据不太可能在完成时到达对等点生成和生成完成意味着没有什么比网络堆栈已经拥有缓冲区的内容的所有权。

Note that the data is unlikely to have reached the peer at the point the completion is generated and the generation of the completion means nothing more than the network stack has taken ownership of the contents of the buffer.

这不同于发送操作。在阻塞模式下使用 send ,对 send 的调用将阻塞,直到网络堆栈使用了你所有的数据提供。对于在非阻塞模式下对 send 的调用,网络栈从缓冲区获取尽可能多的数据,然后返回给您详细的使用量;这意味着您的一些数据已被使用。使用 WSASend ,通常情况下,所有的数据都会在通知之前使用。

This is different to how send operates. With send in blocking mode the call to send will block until the network stack has used all of the data that you have supplied. For calls to send in non-blocking mode the network stack takes as much data as it can from your buffer and then returns to you with details of how much it used; this means that some of your data has been used. With WSASend, generally, all of your data is used before you are notified.

code> WSASend 由于资源限制或网络错误而失败。这是不寻常的,得到一个失败,表明一些数据已发送,但不是所有。通常它都发送OK或没有发送。然而,有可能获得一个错误,表明一些数据已被使用,但不是所有的完成。如何从这一点继续取决于错误(临时资源限制或硬网络故障)以及您在该套接字上挂起的多少其他 WSASend (零或非零)。你只能尝试发送其余的数据,如果你有一个临时资源错误,没有其他突出的 WSASend 调用此套接字;这是更复杂的事实,你不知道临时资源限制情况将通过...如果你有一个临时资源限制诱导部分发送,你有其他 WSASend 调用挂起,那么您应该可能中止连接,因为您可能已经通过从 WSASend 调用发送缓冲区的一部分,然后所有或者部分)的 WSASend 调用。

It's possible for an overlapped WSASend to fail due to resource limits or network errors. It's unusual to get a failure which indicates that some data has been send but not all. Usually it's all sent OK or none sent at all. However it IS possible to get a completion with an error which indicates that some data has been used but not all. How you proceed from this point depends on the error (temporary resource limit or hard network fault) and how many other WSASends you have pending on that socket (zero or non-zero). You can only try and send the rest of the data if you have a temporary resource error and no other outstanding WSASend calls for this socket; and this is made more complicated by the fact that you don't know when the temporary resource limit situation will pass... If you ever have a temporary resource limit induced partial send and you DO have other WSASend calls pending then you should probably abort the connection as you may have garbled your data stream by sending part of the buffer from this WSASend call and then all (or part) of a subsequent WSASend call.

注意,它是一个有用的和b) WSASend 在套接字上未完成的呼叫。这是保持连接充分利用的唯一方法。但是,您应该知道一次有多个重叠的 WSASend 调用挂起的内存和资源使用的影响(参见这里),你有效地控制缓冲区的生命周期(和因此您的代码使用的内存和资源量)到对等体,由于TCP流控制问题)。如果你想变得聪明,请参阅 SIO_IDEAL_SEND_BACKLOG_QUERY SIO_IDEAL_SEND_BACKLOG_CHANGE ...

Note that it's a) useful and b) efficient to have multiple WSASend calls outstanding on a socket. It's the only way to keep the connection fully utilised. You should, however, be aware of the memory and resource usage implications of having multiple overlapped WSASend calls pending at one time (see here) as effectively you are handing control of the lifetime of your buffers (and thus the amount of memory and resources that your code uses) to the peer due to TCP flow control issues). See SIO_IDEAL_SEND_BACKLOG_QUERY and SIO_IDEAL_SEND_BACKLOG_CHANGE if you want to get really clever...

这篇关于在完成端口中调用WSASend()?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆