C++ Winsock RIO:RIOReceive立即返回,没有ByTestTransferred

C++ Winsock RIO:RIOReceive立即返回,没有ByTestTransferred,c++,winsock,winsock2,winsockets,C++,Winsock,Winsock2,Winsockets,我在让winsock RIO工作方面遇到了问题。 似乎每次我发布RIOReceive时,它都会立即返回,并传输0个字节,而我的同伴无法通过它获取消息 发布RIOReceive后,我等待RIODequeCompletion,它立即以numResults=1进行deques,但当我检查RIORESULT结构的ByTestTransferred时,它是0。这告诉我,我没有正确设置这件事,但我找不到文件或例子,告诉我我还应该做什么 互联网似乎对里约几乎没有什么影响。我浏览了这个网站和两台GitHub R

我在让winsock RIO工作方面遇到了问题。 似乎每次我发布RIOReceive时,它都会立即返回,并传输0个字节,而我的同伴无法通过它获取消息

发布RIOReceive后,我等待RIODequeCompletion,它立即以numResults=1进行deques,但当我检查RIORESULT结构的ByTestTransferred时,它是0。这告诉我,我没有正确设置这件事,但我找不到文件或例子,告诉我我还应该做什么

互联网似乎对里约几乎没有什么影响。我浏览了这个网站和两台GitHub RIO服务器

RIOEchoServer和RIOServer_sm9都在GitHub上,但我只能发布两个链接(这是我在这个网站上的第一个问题)

这段代码只是为了让事情得到验证。它当前未设置为使用sendCQ,不能很好地处理错误,等等

以下是准备工作:

void服务器请求线程(){
//初始化缓冲区
//注册大缓冲区
recvBufferMain=rio.RIORegisterBuffer(pRecvBufferMain,bufferSize);
sendBufferMain=rio.RIORegisterBuffer(pSendBufferMain,bufferSize);
if(recvBufferMain==RIO\u无效\u缓冲ID){

cout尝试删除
RIO_MSG_WAITALL
。可能存在一个错误,即您只获得关闭通知(字节==0),而没有获得包含数据的完成。无论采用哪种方式,都可以查看代码是否在没有标记的情况下工作


我的示例服务器和测试在您的硬件上工作吗?

我在将RioReceive与RioNotify和RioDequeueCompletion一起使用时遇到了一个类似的问题,即在我的出列完成结果中接收到零字节。我还会看到WSAEINVAL的“状态”值(无效参数=10022)在我的出列完成结果中,这似乎表示接收调用的WSA错误代码

出现错误的具体原因是,我为receiveBuffer分配了内存,并且我试图将该缓冲指针作为我的缓冲句柄传递给RioReceive的RIO_buffer_段,而不是传递RioRegisterBuffer返回的IntPtr


我完全责怪自己使用了太多的非类型化INTPTR并丢失了类型检查。

为什么您首先要使用RIO,而不是传统的套接字I/O、重叠I/O或I/O完成端口?为什么您要轮询RIO队列,而不是在事情准备就绪时收到通知?并且您对两个发送都使用
recvCQ
RIOCreateRequestQueue()中的recv队列
,您没有对发送队列使用
sendCQ
。我只是查看RIO是否适合我的服务器。您知道,轮询效率不高,但在重载情况下,它提供了自IOCP吃掉循环以来的最高性能。它也很简单,所以我在这里使用它,只是为了在b上获取一些数字oard.Ya,sendCQ没有连接。我暂时删除了它以进行调试,但它会重新启动。谢谢你的提问……你对我为什么不从RIOReceive/RIODequeueCompletion/RIORESULT中获取字节有什么想法吗?我以前从未使用过RIO。IOCP一直是首选的高性能解决方案。我不知道MS为什么会感觉到ne当他们已经有多个套接字API时,我会引入另一个套接字API。在任何情况下,接收到的0字节的结果通常表明该套接字已被对等方关闭。但我没有收到任何WSAENETRESET或WSAENOTCONN错误。是否仍有可能在没有收到这些错误的情况下断开/断开连接?@RemyLebeau:因为C10K问题是昨天的事。我们现在处于C100K甚至C1M问题区域。你现在可以得到40GBit带宽的服务器。每个周期都可能计算,是的,RIO更快。我们很快就会看到一个完整的userland以太网堆栈。1970年的Berkley API和现在已经有20年历史的IOCP不是未来。谢谢Len。这是我们发明的东西之一uting。在我删除该代码后,我还发现我的CQ大小不足以容纳我所有的RQ。我确实阅读了你所有的博客,它们非常有用,但我还没有实际运行代码。我一直专注于TCP,我认为我可以学习理论并构建一个简单的服务器。现实情况有所不同当然,所以我可以回去运行你的UDP服务器/客户端,并从那里开始递增。感谢分享你的工作!我问起在你的硬件上进行测试的原因是,我有一些客户端在不同的机器上安装了奇怪的东西,这显然影响了RIO。所以很高兴得到一个已知的基线示例o首先工作。很高兴你发现了问题。如果你发布的请求(并且完成了)超过了CQ中的空间,那么CQ就会出现损坏的问题;因此你需要小心。
    //start a loop to repin recv buffer for socket
    while (acceptSocket != INVALID_SOCKET) {

        //pin a recv buffer to wait on data
        recvSuccess = rio.RIOReceive(
            requestQueue,           //socketQueue
            &recvBuffer1,           //buffer slice
            1,                      //set to 1
            RIO_MSG_WAITALL,                        //flags
            0);                     //requestContext

        if (recvSuccess == false) {
            cout << "RECV ERROR!!!!!!!!\n";
            printError();
        }

        //wait for recv to post in queue

        //std::this_thread::sleep_for(std::chrono::milliseconds(3000));
        numResults = 0;
        while (numResults == 0) numResults = rio.RIODequeueCompletion(recvCQ, recvArray, 10);

        if (numResults == RIO_CORRUPT_CQ) {

            cout << "RIO_CORRUPT_CQ" << endl;

        } else if (numResults == 0) {

            cout << "no messages on queue\n";

        } else if (numResults > 0) {
            if (recvArray[0].BytesTransferred > 0) {

                //process results
                if (pRecvBufferMain[0] == 'G') {

                    //set respnose html
                    strcpy(pSendBufferMain, responseHTTP);

                    sendSuccess = rio.RIOSend(
                        requestQueue,   //socketQueue
                        &sendBuffer1,   //buffer slice
                        1,              //set to 1
                        0,              //flags
                        0);             //requestContext

                } else if (pRecvBufferMain[0] == 'P') {

                    //process post 


                } else {
                    //recv'd a bad message

                }

            } //end bytesTransferred if statement

            //reset everything and post another recv

        }//end response if statement

        std::this_thread::sleep_for(std::chrono::milliseconds(100));

    }//end while loop for recv'ing

    std::this_thread::sleep_for(std::chrono::milliseconds(100));

}//end while loop for accept'ing

}// end function