TCP IOCP не получит после принятия - PullRequest
0 голосов
/ 22 декабря 2010

Я пытаюсь написать сервер IOCP. По сути, я принимаю новые соединения. В целях моего тестирования я бегу и подключаюсь к 127.0.0.1.

Я создаю псевдо-сокет до вызова AcceptEx (). Как только соединение принято, новый псевдо-сокет используется для связи. Этот новый сокет связан с портом завершения io [CreateIoCompletionPort], затем я назначаю ему несколько параметров [SO_EXCLUSIVEADDRUSE] и [SO_CONDITIONAL_ACCEPT], а затем я вызываю WSARecv () для приема входящих данных.

Проблема в том, что, когда мое удаленное соединение подключается к серверу, оно отправляет данные, но эти данные никогда не принимаются. Мне интересно, если кто-то может предложить некоторые идеи относительно того, почему он не получает данные? Возможно, моя логика ошибочна? Я прошел через мой код несколько раз. ошибок не зафиксировано.

РЕДАКТИРОВАТЬ: Исправлена ​​формулировка. Я создаю сокет перед вызовом AcceptEx ().

Основная логика в моем коде:

// Create socket, associate with IOCP
WSASocket(af, type, proto, lpProtoInfo, g, dwFlags);
HANDLE hIOCP = GetPool()->GetQueueHandle();
CreateIoCompletionPort(hSource, hIOCP, 0, 0) != NULL;

// Server bind and listen
bind(m_shSocket, pAddr, nAddrLen);
listen(m_shSocket, nBacklog);

// Creation of the pseudo socket
SOCKET s = ::WSASocket(m_iSocketAf, m_iSocketType, m_iSocketProto, m_pWpi, m_SocketGroup, m_dwSocketFlags);

DWORD dwBytes;
BOOL bRet = m_fnAcceptEx(m_shSocket, s, chOutput, 0, sizeof(SOCKADDR_STORAGE) + 16, sizeof(SOCKADDR_STORAGE) + 16, &dwBytes, m_pcbAccept);

// ... New Connection comes in, it's accepted ...

// Associate new pseudo socket with IOCP
HANDLE hNewIOCP = GetPool()->GetQueueHandle();
CreateIoCompletionPort((HANDLE) s, hNewIOCP , 0, 0) != NULL;

// ... Remote socket sends ...
// ... Remote socket and Pseudo socket call WSARecv ...
// ... Pseudo socket does not receive ...

ПРИМЕЧАНИЕ. Я попытался отправить данные из псевдо-сокета в удаленный, такая же проблема, как и при отправке данных в обратном направлении.

Ответы [ 3 ]

1 голос
/ 22 декабря 2010

Вам нужно опубликовать некоторый код, но ваше описание не имеет смысла. Это НЕ так, как работают AcceptEx() серверы.

На сервере AcceptEx() вы создаете свой принятый сокет, прежде чем отправлять AcceptEx(). Затем вы публикуете AcceptEx() с сокетом прослушивания, новым сокетом и буфером, который позволяет вам получить удаленный адрес и, необязательно, данные.

Итак, если вы описываете свой код в исходном вопросе, значит, ваш код неверный или вы не используете AcceptEx(). В настоящее время я игнорирую «несколько вариантов», которые вы добавляете в микс, поскольку они просто еще больше запутывают вещи без какого-либо кода для анализа.

Возможно, вам будет интересно загрузить мою бесплатную серверную платформу на основе IOCP , которая включает в себя рабочий AcceptEx() и традиционный Accept() код сервера. Вы можете получить его здесь: http://www.serverframework.com/products---the-free-framework.html

0 голосов
/ 22 декабря 2010

Я понял это.Я идиот.Я отправлял ноль байтов.

0 голосов
/ 22 декабря 2010

Вы звоните GetQueuedCompletionStatus , чтобы получить данные?

Если вы не делаете это просто для того, чтобы научиться самостоятельно, я бы также порекомендовал вам использовать boost ::asio - отличная библиотека, которая позволяет кому-то еще делать утомительный код для обработки портов завершения io.

...