У меня проблемы с работой Winsock RIO.
Кажется, что каждый раз, когда я отправляю сообщение RIOR, оно сразу же возвращается с 0 переданными байтами, и мой коллега не может получить сообщение.
После публикации RIOReceive я жду RIODequeCompletion, который немедленно запрашивает с numResults = 1, но когда я проверяю bytesTransferred структуры RIORESULT, это 0. Это говорит мне, что я не настраиваю эту вещь должным образом, но я могу не найти документы или примеры, которые говорят мне, что еще я должен делать.
В интернете, похоже, очень мало информации о РИО. Я просмотрела MSDN, Лен Холгейт с TheServerFramework, этот сайт и два сервера GitHub RIO.
RIOEchoServer и 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();
}
Я теперь отправляю RIOR получить:
//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 queue\n";
} else if (numResults > 0) {
но когда я проверяю bytesTransferred RIORESULT, это всегда 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), а не завершение с данными в нем. В любом случае было бы интересно посмотреть, работает ли код без флага.
Мои примеры серверов и тестов работают на вашем оборудовании?
Я столкнулся с аналогичной проблемой отсутствия нулевого байта в моем результате завершения с удалением из очереди при использовании RioReceive с RioNotify и RioDequeueCompletion. Я бы также увидел значение «Status» WSAEINVAL (Invalid Parameter = 10022) в моем результате завершения в режиме ожидания, это, кажется, указывает на код ошибки WSA для вызова Receive.
Причина, по которой у меня возникла ошибка, заключается в том, что я выделил память для receiveBuffer и пытался передать этот указатель буфера как мой дескриптор буфера в RIO_BUFFER_SEGMENT, переданном RioReceive вместо передачи IntPtr, возвращенный RioRegisterBuffer.
Я полностью виню себя за использование слишком большого количества нетипизированных IntPtrs и за потерю проверки типов. 🙂