Commit 59563051 authored by jan.koester's avatar jan.koester
Browse files

tests

parent cb10f994
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -261,6 +261,8 @@ namespace netplus {
                continue;
            }

            c->slots[0].csock->setIocpAssociated(true);

            register_con(st, accepted, c);

            ev->ConnectEvent(*c, 0, 0);
+6 −0
Original line number Diff line number Diff line
@@ -242,8 +242,14 @@ namespace netplus {
		bool _Bound    = false;
		bool _Listening = false;

		// Mark this socket as associated with an IOCP handle.
		// Only IOCP-bound sockets should use overlapped WSASend/WSARecv.
		void setIocpAssociated(bool v) { _iocpAssociated = v; }
		bool isIocpAssociated() const  { return _iocpAssociated; }

	protected:
		std::atomic<bool> _pendingIocpWrite{false};
		bool _iocpAssociated = false;
		// ✅ legacy helper still available
		void copyAddrInfo(ULONG_PTR* dest, ULONG_PTR src, size_t srclen);

+30 −15
Original line number Diff line number Diff line
@@ -152,9 +152,35 @@ void tcp::accept(std::unique_ptr<socket>& csock, bool nonblock) {
}

size_t tcp::sendData(buffer& data, int flags) {
    // Copy data to _SendBuffer for async WSASend
    size_t sendlen = data.size;

    // Client sockets (not IOCP-bound): use synchronous WSASend
    if (!isIocpAssociated()) {
        WSABUF wsaBuf;
        wsaBuf.buf = data.data.buf;
        wsaBuf.len = (ULONG)sendlen;

        DWORD bytesSent = 0;
        DWORD dwFlags = (DWORD)flags;

        int ret = ::WSASend(_Socket, &wsaBuf, 1, &bytesSent, dwFlags, nullptr, nullptr);

        if (ret == 0) {
            return (size_t)bytesSent;
        }

        int err = ::WSAGetLastError();
        if (err == WSAEWOULDBLOCK) {
            NetException e;
            e[NetException::Note] << "tcp::sendData: would block";
            throw e;
        }
        NetException e;
        e[NetException::Error] << "tcp::sendData WSASend failed: " << err;
        throw e;
    }

    // IOCP-bound server sockets: use overlapped WSASend
    if (!_SendBuffer) {
        _SendBuffer = std::make_unique<buffer>(sendlen);
    }
@@ -190,19 +216,12 @@ size_t tcp::sendData(buffer& data, int flags) {
}

size_t tcp::recvData(buffer& data, int flags) {
    // First check if we have data from a completed IOCP read
    std::cerr << "[TCP] recvData: _ReadBuffer=" << (_ReadBuffer ? "yes" : "no");
    if (_ReadBuffer) {
        std::cerr << " InternalHigh=" << _ReadBuffer->overlapped.InternalHigh;
    }
    std::cerr << std::endl;
    
    if (_ReadBuffer && _ReadBuffer->overlapped.InternalHigh > 0) {
    // IOCP-bound sockets: check if we have data from a completed IOCP read
    if (isIocpAssociated() && _ReadBuffer && _ReadBuffer->overlapped.InternalHigh > 0) {
        size_t r = (size_t)_ReadBuffer->overlapped.InternalHigh;
        if (r > data.size)
            r = data.size;
        std::copy(_ReadBuffer->data.buf, _ReadBuffer->data.buf + r, data.data.buf);
        std::cerr << "[TCP] recvData: returning " << r << " bytes from InternalHigh, resetting to 0" << std::endl;
        _ReadBuffer->overlapped.InternalHigh = 0;
        return r;
    }
@@ -220,11 +239,9 @@ size_t tcp::recvData(buffer& data, int flags) {
    if (ret == 0) {
        // Success
        if (bytesRecv > 0) {
            std::cerr << "[TCP] recvData: WSARecv returned " << bytesRecv << " bytes" << std::endl;
            return (size_t)bytesRecv;
        }
        // bytesRecv == 0 means connection closed
        std::cerr << "[TCP] recvData: connection closed" << std::endl;
        NetException e;
        e[NetException::Error] << "tcp::recvData: connection closed";
        throw e;
@@ -233,13 +250,11 @@ size_t tcp::recvData(buffer& data, int flags) {
    int err = ::WSAGetLastError();
    if (err == WSAEWOULDBLOCK) {
        // Non-blocking socket with no data - throw Note
        std::cerr << "[TCP] recvData: WSAEWOULDBLOCK, throwing Note" << std::endl;
        NetException e;
        e[NetException::Note] << "tcp::recvData: no data available";
        throw e;
    }
    
    std::cerr << "[TCP] recvData: WSARecv error " << err << std::endl;
    NetException e;
    e[NetException::Error] << "tcp::recvData: WSARecv failed with error " << err;
    throw e;
+29 −1
Original line number Diff line number Diff line
@@ -131,6 +131,33 @@ void udp::accept(std::unique_ptr<socket>& csock, bool nonblock) {
size_t udp::sendData(buffer& data, int flags) {
    size_t sendlen = data.size;

    // Client sockets (not IOCP-bound): use synchronous WSASend
    if (!isIocpAssociated()) {
        WSABUF wsaBuf;
        wsaBuf.buf = data.data.buf;
        wsaBuf.len = (ULONG)sendlen;

        DWORD bytesSent = 0;
        DWORD dwFlags = (DWORD)flags;

        int ret = ::WSASend(_Socket, &wsaBuf, 1, &bytesSent, dwFlags, nullptr, nullptr);

        if (ret == 0) {
            return (size_t)bytesSent;
        }

        int err = ::WSAGetLastError();
        if (err == WSAEWOULDBLOCK) {
            NetException e;
            e[NetException::Note] << "udp::sendData: would block";
            throw e;
        }
        NetException e;
        e[NetException::Error] << "udp::sendData WSASend failed: " << err;
        throw e;
    }

    // IOCP-bound server sockets: use overlapped WSASend
    if (!_SendBuffer) {
        _SendBuffer = std::make_unique<buffer>(sendlen);
    }
@@ -184,7 +211,8 @@ size_t udp::sendTo(buffer& data, int flags) {
}

size_t udp::recvData(buffer& data, int flags) {
    if (_ReadBuffer && _ReadBuffer->overlapped.InternalHigh > 0) {
    // IOCP-bound sockets: check completed IOCP read first
    if (isIocpAssociated() && _ReadBuffer && _ReadBuffer->overlapped.InternalHigh > 0) {
        size_t r = (size_t)_ReadBuffer->overlapped.InternalHigh;
        if (r > data.size)
            r = data.size;