Winsock RIO:RIOReceive returns 立即没有字节传输
Winsock RIO: RIOReceive returns immediately with no bytesTransferred
我在让 winsock RIO 工作时遇到问题。
似乎每次我 post 一个 RIO 立即接收它 returns 并传输 0 个字节,我的对等方无法通过消息。
在 post 执行 RIOReceive 之后,我等待 RIODequeCompletion,它立即使用 numResults = 1 进行双端排队,但是当我检查 RIORESULT 结构的 bytesTransferred 时,它是 0。这告诉我我是没有正确设置这个东西,但我找不到告诉我我还应该做什么的文档或示例。
互联网上关于 RIO 的资料似乎很少。我查看了 MSDN, Len Holgate with TheServerFramework、这个站点和两个 GitHub RIO 服务器。
RIOEchoServer 和 RIOServer_sm9 在 GitHub 上,但我不能 post 超过两个链接(这是我在这个网站上的第一个问题)。
这段代码只是为了证明事情。目前未设置为使用 sendCQ,不能很好地处理错误等...
准备工作如下:
void serverRequestThread() {
//init buffers
//register big buffers
recvBufferMain = rio.RIORegisterBuffer(pRecvBufferMain, bufferSize);
sendBufferMain = rio.RIORegisterBuffer(pSendBufferMain, bufferSize);
if (recvBufferMain == RIO_INVALID_BUFFERID) {
cout << "RIO_INVALID_BUFFERID" << endl;
}
if (sendBufferMain == RIO_INVALID_BUFFERID) {
cout << "RIO_INVALID_BUFFERID" << endl;
}
//create recv buffer slice
recvBuffer1.BufferId = recvBufferMain;
recvBuffer1.Offset = 0;
recvBuffer1.Length = 10000;
//create send buffer slice
sendBuffer1.BufferId = sendBufferMain;
sendBuffer1.Offset = 0;
sendBuffer1.Length = 10000;
//completion queue
recvCQ = rio.RIOCreateCompletionQueue(CQsize, NULL);
sendCQ = rio.RIOCreateCompletionQueue(CQsize, NULL);
if (recvCQ == RIO_INVALID_CQ) {
cout << "RIO_INVALID_CQ" << endl;
}
if (sendCQ == RIO_INVALID_CQ) {
cout << "RIO_INVALID_CQ" << endl;
}
//start a loop for newly accept'd socket
while (recvCQ != RIO_INVALID_CQ && sendCQ != RIO_INVALID_CQ) {
//get accept'd socket
struct sockaddr_in saClient;
int iClientSize = sizeof(saClient);
acceptSocket = accept(listenSocket, (SOCKADDR*)&saClient, &iClientSize);
if (acceptSocket == INVALID_SOCKET) {
cout << "Invalid socket" << endl;
printError();
}
//register request queue
requestQueue = rio.RIOCreateRequestQueue(
acceptSocket, //socket
10, //max RECVs on queue
1, //max recv buffers, set to 1
10, //max outstanding sends
1, //max send buffers, set to 1
recvCQ, //recv queue
recvCQ, //send queue
pOperationContext //socket context
);
if (requestQueue == RIO_INVALID_RQ) {
cout << "RIO_INVALID_RQ" << endl;
printError();
}
我现在post一个RIOReceive:
//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));
我一调用 RIODequeCompletion,它就 returns 1:
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) {
但是当我检查 RIORESULT 的 bytesTransferred 时,它总是 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
就像我说的,我可能没有正确使用 RIOReceive,and/or 我没有设置我需要的正确套接字选项(none 现在)。
感谢您对此提供的任何帮助。
尝试删除 RIO_MSG_WAITALL
。可能存在一个错误,您只能收到关闭通知(字节 == 0)而不是完成其中的数据。无论哪种方式,看看代码是否可以在没有标志的情况下工作都会很有趣。
我的示例服务器和测试是否适用于您的硬件?
我在将 RioReceive 与 RioNotify 和 RioDequeueCompletion 一起使用时遇到了类似的问题,即在我的出队完成结果中有零字节接收。我还会在我的出队完成结果中看到 WSAEINVAL(无效参数 = 10022)的 'Status' 值,这似乎表明接收调用的 WSA 错误代码。
我出现错误的具体原因是因为我已经为 receiveBuffer 分配了内存并且我试图将 那个缓冲区指针 作为我在 [=21= 中的缓冲区句柄] 传递给 RioReceive,而不是传递 RioRegisterBuffer 返回的 IntPtr。
我完全责怪自己使用了太多未类型化的 IntPtr 并丢失了类型检查。 :)
我在让 winsock RIO 工作时遇到问题。 似乎每次我 post 一个 RIO 立即接收它 returns 并传输 0 个字节,我的对等方无法通过消息。
在 post 执行 RIOReceive 之后,我等待 RIODequeCompletion,它立即使用 numResults = 1 进行双端排队,但是当我检查 RIORESULT 结构的 bytesTransferred 时,它是 0。这告诉我我是没有正确设置这个东西,但我找不到告诉我我还应该做什么的文档或示例。
互联网上关于 RIO 的资料似乎很少。我查看了 MSDN, Len Holgate with TheServerFramework、这个站点和两个 GitHub RIO 服务器。
RIOEchoServer 和 RIOServer_sm9 在 GitHub 上,但我不能 post 超过两个链接(这是我在这个网站上的第一个问题)。
这段代码只是为了证明事情。目前未设置为使用 sendCQ,不能很好地处理错误等...
准备工作如下:
void serverRequestThread() {
//init buffers
//register big buffers
recvBufferMain = rio.RIORegisterBuffer(pRecvBufferMain, bufferSize);
sendBufferMain = rio.RIORegisterBuffer(pSendBufferMain, bufferSize);
if (recvBufferMain == RIO_INVALID_BUFFERID) {
cout << "RIO_INVALID_BUFFERID" << endl;
}
if (sendBufferMain == RIO_INVALID_BUFFERID) {
cout << "RIO_INVALID_BUFFERID" << endl;
}
//create recv buffer slice
recvBuffer1.BufferId = recvBufferMain;
recvBuffer1.Offset = 0;
recvBuffer1.Length = 10000;
//create send buffer slice
sendBuffer1.BufferId = sendBufferMain;
sendBuffer1.Offset = 0;
sendBuffer1.Length = 10000;
//completion queue
recvCQ = rio.RIOCreateCompletionQueue(CQsize, NULL);
sendCQ = rio.RIOCreateCompletionQueue(CQsize, NULL);
if (recvCQ == RIO_INVALID_CQ) {
cout << "RIO_INVALID_CQ" << endl;
}
if (sendCQ == RIO_INVALID_CQ) {
cout << "RIO_INVALID_CQ" << endl;
}
//start a loop for newly accept'd socket
while (recvCQ != RIO_INVALID_CQ && sendCQ != RIO_INVALID_CQ) {
//get accept'd socket
struct sockaddr_in saClient;
int iClientSize = sizeof(saClient);
acceptSocket = accept(listenSocket, (SOCKADDR*)&saClient, &iClientSize);
if (acceptSocket == INVALID_SOCKET) {
cout << "Invalid socket" << endl;
printError();
}
//register request queue
requestQueue = rio.RIOCreateRequestQueue(
acceptSocket, //socket
10, //max RECVs on queue
1, //max recv buffers, set to 1
10, //max outstanding sends
1, //max send buffers, set to 1
recvCQ, //recv queue
recvCQ, //send queue
pOperationContext //socket context
);
if (requestQueue == RIO_INVALID_RQ) {
cout << "RIO_INVALID_RQ" << endl;
printError();
}
我现在post一个RIOReceive:
//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));
我一调用 RIODequeCompletion,它就 returns 1:
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) {
但是当我检查 RIORESULT 的 bytesTransferred 时,它总是 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
就像我说的,我可能没有正确使用 RIOReceive,and/or 我没有设置我需要的正确套接字选项(none 现在)。
感谢您对此提供的任何帮助。
尝试删除 RIO_MSG_WAITALL
。可能存在一个错误,您只能收到关闭通知(字节 == 0)而不是完成其中的数据。无论哪种方式,看看代码是否可以在没有标志的情况下工作都会很有趣。
我的示例服务器和测试是否适用于您的硬件?
我在将 RioReceive 与 RioNotify 和 RioDequeueCompletion 一起使用时遇到了类似的问题,即在我的出队完成结果中有零字节接收。我还会在我的出队完成结果中看到 WSAEINVAL(无效参数 = 10022)的 'Status' 值,这似乎表明接收调用的 WSA 错误代码。
我出现错误的具体原因是因为我已经为 receiveBuffer 分配了内存并且我试图将 那个缓冲区指针 作为我在 [=21= 中的缓冲区句柄] 传递给 RioReceive,而不是传递 RioRegisterBuffer 返回的 IntPtr。
我完全责怪自己使用了太多未类型化的 IntPtr 并丢失了类型检查。 :)