Commit 0c56da28 authored by jan.koester's avatar jan.koester
Browse files

test

parent 4b60ff57
Loading
Loading
Loading
Loading
+79 −63
Original line number Diff line number Diff line
@@ -163,40 +163,55 @@ void netplus::tcp::accept(std::unique_ptr <socket> &csock) {
    }
}

void netplus::tcp::accept(LPFN_ACCEPTEX lpfnAcceptEx, std::unique_ptr<socket>& next, buffer& data) {
void netplus::tcp::accept(LPFN_ACCEPTEX lpfnAcceptEx,
                          std::unique_ptr<socket>& csock,
                          buffer& data)
{
    NetException exception;

    // Socket erstellen
    next->_Socket = ::WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED);
    if (!csock) {
        csock = std::make_unique<netplus::tcp>();
    }
    tcp* cssock = static_cast<tcp*>(csock.get());

    if (next->_Socket == INVALID_SOCKET) {
        NetException exception;
    // neues Accept-Socket erzeugen
    const addrinfo* ai = reinterpret_cast<const addrinfo*>(this->_SocketInfo);

    cssock->_Socket = WSASocket(ai->ai_family,
                                ai->ai_socktype,
                                ai->ai_protocol,
                                nullptr,
                                0,
                                WSA_FLAG_OVERLAPPED);

    if (cssock->_Socket == INVALID_SOCKET) {
        exception[NetException::Error] << "WSASocket failed: " << WSAGetLastError();
        throw exception;
    }

    // WICHTIG: Overlapped Struktur vor jedem Aufruf nullen!
    std::memset(&data.overlapped, 0, sizeof(OVERLAPPED));
    // IOCP Metadaten vorbereiten
    data.operation = OP_ACCEPT;

    DWORD bytesReceived = 0;
    // Jeweils 16 Bytes Reserve zustzlich zur sockaddr Struktur (Vorschrift von Microsoft)
    DWORD addrLen = sizeof(sockaddr_in) + 16;

    BOOL ok = lpfnAcceptEx(
        (SOCKET)_Socket,
        (SOCKET)next->_Socket,
        data.data.buf,
        0,         // dwReceiveDataLength: 0 bedeutet, wir wollen nur den Connect-Event
        addrLen,   // dwLocalAddressLength
        addrLen,   // dwRemoteAddressLength
        &bytesReceived,
    std::memset(&data.overlapped, 0, sizeof(WSAOVERLAPPED));

    DWORD dwbytes = 0;

    // AcceptEx posten
    const BOOL ok = lpfnAcceptEx(
        (SOCKET)this->_Socket,          // listen socket
        (SOCKET)cssock->_Socket,        // accepted socket
        data.data.buf,                  // AcceptEx address buffer
        0,                              // keine Nutzdaten beim accept
        sizeof(SOCKADDR_STORAGE) + 16,
        sizeof(SOCKADDR_STORAGE) + 16,
        &dwbytes,
        &data.overlapped
    );

    if (!ok) {
        int err = WSAGetLastError();
        if (err != ERROR_IO_PENDING) {
            NetException exception;
        const int err = WSAGetLastError();
        if (err != WSA_IO_PENDING) {
            closesocket(cssock->_Socket);
            cssock->_Socket = INVALID_SOCKET;
            exception[NetException::Error] << "AcceptEx failed: " << err;
            throw exception;
        }
@@ -374,64 +389,65 @@ void netplus::tcp::getAddress(std::string& addr) {
}

// New overloads that accept explicit OVERLAPPED pointer
void netplus::tcp::sendDataWSA(buffer& b, int flags) {
    DWORD bytes = 0;
void netplus::tcp::sendDataWSA(buffer& data, int flags)
{
    NetException exception;

    data.operation = OP_WRITE;
    std::memset(&data.overlapped, 0, sizeof(WSAOVERLAPPED));

    DWORD sent = 0;

    int rc = WSASend(
        _Socket,
        &b.data,
        (SOCKET)_Socket,
        &data.data,
        1,
        &bytes,
        &sent,
        flags,
        &b.overlapped,
        &data.overlapped,
        nullptr
    );

    if (rc == 0) {
        // completed inline
        return;
    }

    if (rc == SOCKET_ERROR) {
        int err = WSAGetLastError();
    if (err == WSA_IO_PENDING) {
        // async send queued successfully
        return;
        if (err != WSA_IO_PENDING) {
            exception[NetException::Error] << "WSASend failed: " << err;
            throw exception;
        }
    }

    NetException e;
    e[NetException::Error] << "WSASend failed: " << err;
    throw e;
}

static inline uint64_t now_ms() {
    return GetTickCount64();
}

#define IOLOG(fmt, ...) \
    do { \
        std::fprintf(stderr, "[%10" PRIu64 " ms][tid=%lu] " fmt "\n", \
            now_ms(), GetCurrentThreadId(), __VA_ARGS__); \
        std::fflush(stderr); \
    } while (0)


void netplus::tcp::recvDataWSA(buffer& data, int flags) {
    DWORD dwBytes = 0;
    DWORD dwFlags = (DWORD)flags;
void netplus::tcp::recvDataWSA(buffer& data, int flags)
{
    NetException exception;

    int rc = ::WSARecv(_Socket, &data.data, 1, &dwBytes, &dwFlags, &data.overlapped, nullptr);
    int err = (rc == SOCKET_ERROR) ? WSAGetLastError() : 0;
    data.operation = OP_READ;
    std::memset(&data.overlapped, 0, sizeof(WSAOVERLAPPED));

    IOLOG("WSARecv: sock=%llu rc=%d err=%d dwBytes=%lu flags_in=%d buf=%p len=%lu ov=%p",
        (unsigned long long)_Socket, rc, err, (unsigned long)dwBytes,
        flags, data.data.buf, (unsigned long)data.data.len, &data.overlapped);
    DWORD received = 0;
    DWORD dwFlags = flags;

    if (rc == 0) return;
    if (err == WSA_IO_PENDING) return;
    int rc = WSARecv(
        (SOCKET)_Socket,
        &data.data,
        1,
        &received,
        &dwFlags,
        &data.overlapped,
        nullptr
    );

    NetException e;
    e[NetException::Error] << "WSARecv failed: " << err;
    throw e;
    if (rc == SOCKET_ERROR) {
        int err = WSAGetLastError();
        if (err != WSA_IO_PENDING) {
            exception[NetException::Error] << "WSARecv failed: " << err;
            throw exception;
        }
    }
}

void netplus::tcp::prime_read(buffer& b) {