如何使用WSASend()和IOCP模拟阻塞的send()? [英] How to simulate a blocking send() using WSASend() and IOCP?

查看:459
本文介绍了如何使用WSASend()和IOCP模拟阻塞的send()?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个问题不是必需的,因为WSASend()函数可以固有地在阻塞模式下使用,即使套接字具有重叠的属性并与完成端口相关联也是如此.在阻塞模式下使用它:只是在调用WSASend() 时不提供重叠的结构或完成例程.

This question is not necessary, as the WSASend() function can inherently be used in a blocking mode, even if the socket has the overlapped attribute and is associated with a completion port. To use it in a blocking mode: just don't supply an overlapped structure or a completion routine when calling WSASend().

我想确保在发送数据时,仅当此数据已放置在发送缓冲区中时,该函数才会返回.这就是我想出的(伪代码):

I want to make sure that when I send data, the function will only return when this data has been placed in the send buffer. So this is what I come up with (pseudo code):

void WSASend_Block(char *arr, int length)
{
    OVERLAPPED overlapped;
    overlapped.hEvent = someEvent;
    int result = WSASend(arr, length, &overlapped);

    while(true)
    {
        if (result == 0) // IO operation has been scheduled
        {
            wait(overlapped.hEvent, INFINITE); // block until data is placed into send buffer
            break;
        }
        else
        {
            result = WSASend(arr, length, &overlapped);
        }
    }
}

推荐答案

您为什么要这样做?

您认为它能实现什么?

来自 MSDN文档用于WSASend

对于具有重叠属性的套接字,WSASend使用重叠的I/O 除非lpOverlapped和lpCompletionRoutine参数都是 空值.在这种情况下,该套接字将被视为非重叠套接字.

For sockets with the overlapped attribute, WSASend uses overlapped I/O unless both the lpOverlapped and lpCompletionRoutine parameters are NULL. In that case, the socket is treated as a non-overlapped socket.

因此,只需不提供完成例程或OVERLAPPED结构,该调用将成为非重叠"调用.这就是您想要的,直到数据被复制到网络堆栈的发送缓冲区之前,调用一直阻塞...

So, simply don't supply a completion routine OR an OVERLAPPED structure and the call will become a "non overlapped" call. Which is what you want, a call which blocks until the data is copied into the network stack's send buffer...

此外,我希望所讨论的代码不会使用IOCP,因为如果使用IOCP,它可能会崩溃,也许不是现在,但是最终会崩溃.您有比赛条件.如果您使用的是IOCP,则OVERLAPPED结构必须存在,直到完成后才被调用GetQueuedCompletionStatus()的线程处理.您可以通过这种方式使用重叠的I/O,只是不要将套接字与IOCP关联.等待事件被信号通知的事实并不意味着您在GetQueuedCompletionStatus()上阻塞的线程之一将已检索完成并对其进行处理,并完成了在调用之前在堆栈上创建的OVERLAPPED结构的操作.等待事件的调用完成,该函数返回.

Also, I hope the code in question is NOT using an IOCP as it will crash horribly if it is, maybe not now, but eventually. You have a race condition. If you're using IOCP then the OVERLAPPED structure MUST exist until after the completion occurs and is processed by a thread calling GetQueuedCompletionStatus(). You could use overlapped I/O this way, just do NOT associate the socket with an IOCP. The fact that you wait for the event to be signalled does not mean that one of your threads blocking on GetQueuedCompletionStatus() will have retrieved the completion and dealt with it and finished touching the OVERLAPPED structure that you have created on the stack before the call waiting on the event completes and that function returns.

这篇关于如何使用WSASend()和IOCP模拟阻塞的send()?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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