我正在开发管理req / res主题的服务器 - 客户端应用程序,并对某些消息进行扇出。消息以重叠模式与WSASend
一起发送,并提供完成例程。注意到WSASend
触发发件人完成例程后,WSARead
下一次发送。虽然在WSARead
之前的服务器发送的发送没有触发完成例程。为什么会这样?
bool CCommunicationServer::ManageReadMessage(UCHAR index)
{
OVERLAPPED_EX *over = m_readov[index];
DWORD bytes = 0, flags = 0;
if (WSARecv(over->socket, &(over->wsabuf), 1, &bytes, &flags, over, &CCommunicationServer::WorkerReadRoutine) == SOCKET_ERROR) {
bytes = WSAGetLastError();
if (bytes != WSA_IO_PENDING) {
LOG(ERROR) << std::endl << "WSARecv() failed w/err " << bytes;
shutdown(m_readov[index]->socket, SD_BOTH);
return FALSE;
}
}
return TRUE;
}
bool CCommunicationServer::ManageSendMessage(UCHAR index, char* msg, OVERLAPPED_EX *moreover)
{
OVERLAPPED_EX *over = moreover;
DWORD bytes = 0;
SOCKET socket = m_readov[index] != NULL ? m_readov[index]->socket : NULL;
if (!over) {
ScopedLock lock(&m_lock);
if (!msg) {
LOG(WARNING) << "Empty send! Ignoring!";
return FALSE;
} else if (m_readov[index] != NULL) {
LOG(DEBUG) << ++created << "\t:\t" << deleted << "\t\t\t\r";
over = new OVERLAPPED_EX(this, m_readov[index]->socket, index, msg);
} else {
return FALSE;
}
}
if (WSASend(socket, &(over->wsabuf), 1, &bytes, 0, (LPWSAOVERLAPPED)over, &CCommunicationServer::WorkerSendRoutine) == SOCKET_ERROR) {
bytes = bytes = WSAGetLastError();
if (bytes != WSA_IO_PENDING) {
LOG(ERROR) << std::endl << "WSASend() failed w/err " << bytes;
shutdown(socket, SD_BOTH);
LOG(DEBUG) << created << "\t:\t" << ++deleted << "\t\t\t\r";
delete over;
return FALSE;
}
}
return TRUE;
}
以下是完成例程:
void CALLBACK CCommunicationServer::WorkerReadRoutine(DWORD Error, DWORD BytesTransferred, LPWSAOVERLAPPED Overlapped, DWORD InFlags)
{
OVERLAPPED_EX *over = (OVERLAPPED_EX*)Overlapped;
if (Error)
return;
if (BytesTransferred > 0) {
over->server->GetRequest(over);
}
over->server->ManageReadMessage(over->index);
}
void CALLBACK CCommunicationServer::WorkerSendRoutine(DWORD Error, DWORD BytesTransferred, LPWSAOVERLAPPED Overlapped, DWORD InFlags)
{
OVERLAPPED_EX *over = (OVERLAPPED_EX*)Overlapped;
if (Error || over->wsabuf.len == BytesTransferred) {
LOG(DEBUG) << over->server->created << "\t:\t" << ++over->server->deleted << "\t\t\t\r";
delete over;
} else {
over->wsabuf.buf += BytesTransferred;
over->wsabuf.len -= BytesTransferred;
over->server->ManageSendMessage(over->index, NULL, over);
}
}
变量created
和deleted
显示创建了多少OVERLAPPED_EX
个结构,然后释放以避免内存泄漏。