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