bool NetSocket::PostSend() { int status = _netStatus.load(); int expected = status | NET_STATUS_CONNECTED & NET_STATUS_RECV_PENDING & (!NET_STATUS_SEND_PENDING); int desired = expected | NET_STATUS_SEND_PENDING; if (!_netStatus.compare_exchange_strong(expected, desired)) { DebugPrint("PostSend: netStatus exchange failed: current(0x%x)", status); return false; } size_t sendQueueSize = _sendQueue.unsafe_size(); if (sendQueueSize == 0) { DebugPrint("PostSend: send queue is empty."); return false; } NetIoBuffer* sendOP = new NetIoBuffer(NetCompletionOP::OP_WRITE); sendOP->Reset(GetSocket()); std::vector<WSABUF> wbufs; wbufs.resize(sendQueueSize); MemoryBlock* buffer = nullptr; int idx = 0; while (_sendQueue.try_pop(buffer)) { wbufs[idx].buf = buffer->GetData(); wbufs[idx].len = buffer->GetDataLen(); sendOP->PushData(buffer); idx++; } int rc = WSASend( GetSocket(), &(wbufs[0]), static_cast<DWORD>(wbufs.size()), NULL, 0, &(sendOP->ol), NULL ); if (rc == SOCKET_ERROR) { if (WSAGetLastError() != WSA_IO_PENDING) { DebugPrint("PostSend: WSASend* failed: %s", SocketGetLastErrorString().c_str()); Disconnect(NET_CTYPE_SYSTEM); delete sendOP; return false; } } return true; }
void NetSocket::Send(char* data, uint16 dataLen) { PacketHeaderObj packet; packet.SetHeader(dataLen); MemoryBlock* buffer = g_memoryPool.GetBuffer(dataLen + PACKET_HEADER_SIZE); memcpy(buffer->GetData(), packet.header.blob, PACKET_HEADER_SIZE); memcpy(buffer->GetData() + PACKET_HEADER_SIZE, data, dataLen); _sendPendingQueue.push(buffer); PrepareSend(); }
void NetSocket::OnRecv(NetCompletionOP* recvOP, DWORD bytesTransfered) { REFLIB_ASSERT_RETURN_IF_FAILED(recvOP, "NetIoBuffer is null"); NetIoBuffer *ioBuffer = reinterpret_cast<NetIoBuffer*>(recvOP); MemoryBlock* buffer; if (buffer = ioBuffer->PopData()) { OnRecvData(buffer->GetData(), bytesTransfered); } else { Disconnect(NetCloseType::NET_CTYPE_SYSTEM); } delete ioBuffer; _netStatus.fetch_and(~NET_STATUS_RECV_PENDING); PostRecv(); }
bool NetSocket::PostRecv() { _netStatus.fetch_or(NET_STATUS_RECV_PENDING); NetIoBuffer* recvOP = new NetIoBuffer(NetCompletionOP::OP_READ); recvOP->Reset(GetSocket()); MemoryBlock* buffer = recvOP->Alloc(MAX_PACKET_SIZE); WSABUF wbuf; wbuf.buf = buffer->GetData(); wbuf.len = buffer->GetDataLen(); DWORD flags = 0; int rc = WSARecv( GetSocket(), &wbuf, 1, NULL, &flags, &(recvOP->ol), NULL ); if (rc == SOCKET_ERROR) { int error = WSAGetLastError(); if (error != WSA_IO_PENDING) { delete recvOP; DebugPrint("PostRecv: WSARecv* failed: %s", SocketGetErrorString(error).c_str()); Disconnect(NET_CTYPE_SYSTEM); return false; } } return true; }