diff --git a/Common/Cpp/Sockets/ClientSocket_WinSocket.cpp b/Common/Cpp/Sockets/ClientSocket_WinSocket.cpp index cfc5602942..37f630c19b 100644 --- a/Common/Cpp/Sockets/ClientSocket_WinSocket.cpp +++ b/Common/Cpp/Sockets/ClientSocket_WinSocket.cpp @@ -126,10 +126,10 @@ size_t ClientSocket_WinSocket::send(const void* data, size_t bytes, std::chrono: int current = (int)std::min(bytes, BLOCK_SIZE); int current_sent = ::send(socket, ptr, current, 0); if (current_sent != SOCKET_ERROR){ + // A partial send is not an error: advance and keep looping + // until everything is written or the deadline/state ends + // the send, the same way the POSIX and Qt backends do. sent += current_sent; - if (current_sent != current){ - return sent; - } ptr += current_sent; bytes -= current_sent; continue; diff --git a/Common/Cpp/Sockets/ServerSocket_WinSocket.cpp b/Common/Cpp/Sockets/ServerSocket_WinSocket.cpp index 7779c00122..8f1b1d4d24 100644 --- a/Common/Cpp/Sockets/ServerSocket_WinSocket.cpp +++ b/Common/Cpp/Sockets/ServerSocket_WinSocket.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include "Common/Cpp/Concurrency/ThreadPool.h" #include "ServerSocket_WinSocket.h" @@ -191,7 +192,12 @@ size_t ServerSocket_WinSocket::send(const void* data, size_t bytes, std::chrono: return sent; } - int current_sent = ::send(socket, ptr, (int)bytes, 0); + // "::send" takes an "int" length, so chunk the send the same + // way the WinSocket client does; sending a payload larger than + // 2 GiB in one call would wrap the length negative. + constexpr size_t BLOCK_SIZE = (size_t)1 << 30; + const int current = (int)std::min(bytes, BLOCK_SIZE); + int current_sent = ::send(socket, ptr, current, 0); if (current_sent != SOCKET_ERROR){ sent += (size_t)current_sent; ptr += current_sent;