我正在开发管理 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