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::PrepareSend() { unsigned int sendPacketSize = 0; MemoryBlock* buffer = nullptr; while (!_sendPendingQueue.empty() && (_sendQueue.unsafe_size() < MAX_SEND_ARRAY_SIZE) && (sendPacketSize < DEF_SOCKET_BUFFER_SIZE)) { _sendPendingQueue.try_pop(buffer); _sendQueue.push(buffer); sendPacketSize += buffer->GetDataLen(); } if (sendPacketSize > 0) PostSend(); }
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; }