Loading src/windows/tcp.cpp +79 −63 Original line number Diff line number Diff line Loading @@ -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; } Loading Loading @@ -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) { Loading Loading
src/windows/tcp.cpp +79 −63 Original line number Diff line number Diff line Loading @@ -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; } Loading Loading @@ -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) { Loading