예제 #1
0
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;
}
예제 #2
0
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();
}
예제 #3
0
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;
}