winsock RIO 작동에 문제가 있습니다. RIOReceive를 게시 할 때마다 즉시 0 바이트가 전송되고 내 피어가 메시지를 가져올 수없는 것으로 보입니다.Winsock RIO : RIOReceive는 bytesTransferred없이 즉시 반환합니다.
RIOReceive 게시 한 후 RIODequeCompletion 즉시 numResults 함께 deques = 1,하지만 내가 RIORESULT 구조체의 bytesTransferred 검사 할 때 0입니다.이 제대로 설정하지 않고 있음을 말해줍니다. ,하지만 내가해야할 일을 알려주는 문서 나 예제를 찾을 수는 없습니다.
인터넷에 RIO가 거의없는 것 같습니다. MSDN, Len Holgate with TheServerFramework,이 사이트 및 2 개의 GitHub RIO 서버를 살펴 보았습니다.
RIOEchoServer 및 RIOServer_sm9는 GitHub에 있지만 두 개 이상의 링크를 게시 할 수 없습니다 (이 사이트에서는 내 첫 번째 질문입니다).
이 코드는 입증 된 것입니다.
//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));
로 : 나는 지금 RIOReceive을 게시
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();
}
: 현재, 여기
은 준비 작업의 ... 등 잘 오류를 처리하지 않습니다 sendCQ를 사용하도록 설정 아니에요 내가 RIODequeCompletion를 호출하는 즉시, 그것은 하나가 반환 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을 사용하지 않는, 및/또는 내가 (지금은 없음)에 필요한 올바른 소켓 옵션을 설정하고 있지 않다.
감사합니다.
기존 소켓 I/O 또는 겹친 I/O 또는 I/O 완료 포트 대신 RIO를 처음 사용하는 이유는 무엇입니까?왜 준비가되었는지 알리는 대신 RIO 대기열을 폴링하는 이유는 무엇입니까? 그리고'RIOCreateRequestQueue()'에서 send와 recv 대기열 모두에 대해'recvCQ'를 사용하고 있고, send 대기열에 대해'sendCQ'를 사용하고 있지 않습니다. –
저는 RIO가 내 서버에 적합한 지 확인하려고합니다. 아시다시피 폴링은 효율적이지 않지만 부하가 많은 경우 IOCP가주기를 먹을 것이므로 가장 높은 성능을 제공합니다. 또한 가장 간단한 방법이기 때문에 여기에서 보드를 사용하여 보드에 숫자를 표시합니다. 예, sendCQ가 연결되지 않았습니다. 내가 디버깅을 위해 일시적으로 그것을 제거하지만, 다시 갈거야. 요청 주셔서 감사합니다 ... 왜 내가 RIOReceive/RIODequeueCompletion/RIORESULT의 바이트를 가져 오지 않을거야에 대한 아이디어가 있습니까? – Michael220
전 RIO를 사용한 적이 없습니다. IOCP는 언제나 선호되는 고성능 솔루션이었습니다. MS가 왜 이미 여러 소켓 API를 가지고있을 때 또 다른 소켓 API를 소개해야 할 필요성을 느꼈는지 나는 모른다. 어쨌든 0 바이트의 결과는 대개 소켓이 피어에 의해 닫혔다는 것을 나타냅니다. –