Winsock RIO:RIOSReceive立即返回,没有字节转移
Winsock RIO: RIOReceive returns immediately with no bytesTransferred
我在使winsock RIO工作时遇到问题。似乎每次我发布RIOSReceive时,它都会立即返回,并传输0个字节,而我的对等方无法通过。
在发布RIOSReceive之后,我等待RIODequeCompletion,它会立即用numResults=1进行deques,但当我检查RIOSRESULT结构的bytesTransfer时,它是0。这告诉我没有正确设置这件事,但我找不到文档或示例来告诉我还应该做什么。
互联网上似乎很少有关于RIO的信息。我浏览了MSDN、Len Holgate with TheServerFramework、这个网站和两个GitHub RIO服务器。
RIOEcoServer和RIOServer_sm9在GitHub上,但我不能发布超过两个链接(这是我在这个网站上的第一个问题)。
这段代码只是为了让事情得到验证。它目前没有设置为使用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();
}
我现在发布一个RIOEive:
//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,它就会返回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 queuen";
} else if (numResults > 0) {
但是当我检查RIORRESULT的字节传输时,它总是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,和/或我没有设置所需的正确套接字选项(目前没有)。
我很感激你的帮助。
尝试删除RIO_MSG_WAITALL
。可能存在这样一个错误,即您只得到关闭通知(字节==0),而没有得到包含数据的完成。不管怎样,看看代码是否在没有标志的情况下工作都会很有趣。
我的示例服务器和测试在您的硬件上工作吗?
在使用带有RioNotify和RioDequeueCompletion的RioReceive时,我遇到了一个类似的问题,即在出列完成结果中接收到零字节。我还会在我的出队完成结果中看到WSAEINVAL的"Status"值(无效参数=10022),这似乎表明Receive调用的WSA错误代码。
我出现错误的特殊原因是,我为receiveBuffer分配了内存,并且我试图在给RioReceive的RIO_buffer_SEGMENT中传递缓冲区指针作为缓冲区句柄,而不是传递RioRegisterBuffer返回的IntPtr。
我完全责怪自己使用了太多未键入的IntPtr并丢失了类型检查。:)
- 从不同线程使用int64的不同字节安全吗
- 将Integer转换为4字节的unsined字符矢量(按大端字节顺序)
- 在UNIX系统中使用DIR查找文件的字节大小
- 如何使用Crypto++并为RSA返回可打印的字节/字符数组
- std::当在256字节边界上写入整数时,流的奇怪行为
- 当比特(而不是字节)的顺序至关重要时的持久性
- 我是否需要在下一次转移时将所有权*转移回转移队列
- 从文件中读取多个字节,并将它们存储在C++中进行比较
- 如何在文件中查找字节序列
- luaL_dofile在已知良好的字节码上失败,可以使用未编译的版本
- 字节到位运算符重载C++
- 在java中读取c++字节的位字段
- 使用 std::vector::reverse_iterator 将 int 序列化为字节向量?
- 字节真的是最小可寻址单元吗
- struct.error:解压缩 C++ 结构时,解包需要 288 字节的缓冲区
- 读取文件中所有可能的十六进制 16 字节序列并打印每个序列
- 如何使用 OpenCV 解码在两个 UWP 应用之间发送的图像字节?
- 如何将字节数组元素替换为修改的十六进制 ASCII 符号?
- asn1c 不会从 asn.1 模块中提取八位字节字符串的默认值
- Winsock RIO:RIOSReceive立即返回,没有字节转移