From ebd1b636e5bf0f8fa6d210690582757e8b47f141 Mon Sep 17 00:00:00 2001 From: James Cowgill Date: Fri, 8 May 2015 21:14:39 +0100 Subject: Imported Upstream version 2.3+dfsg --- src/SFML/Network/TcpSocket.cpp | 51 +++++++++++++++++++++++++++++++++--------- 1 file changed, 41 insertions(+), 10 deletions(-) (limited to 'src/SFML/Network/TcpSocket.cpp') diff --git a/src/SFML/Network/TcpSocket.cpp b/src/SFML/Network/TcpSocket.cpp index ac6d6b9..5a032ef 100644 --- a/src/SFML/Network/TcpSocket.cpp +++ b/src/SFML/Network/TcpSocket.cpp @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////// // // SFML - Simple and Fast Multimedia Library -// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com) +// Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. @@ -218,6 +218,18 @@ void TcpSocket::disconnect() //////////////////////////////////////////////////////////// Socket::Status TcpSocket::send(const void* data, std::size_t size) +{ + if (!isBlocking()) + err() << "Warning: Partial sends might not be handled properly." << std::endl; + + std::size_t sent; + + return send(data, size, sent); +} + + +//////////////////////////////////////////////////////////// +Socket::Status TcpSocket::send(const void* data, std::size_t size, std::size_t& sent) { // Check the parameters if (!data || (size == 0)) @@ -227,16 +239,22 @@ Socket::Status TcpSocket::send(const void* data, std::size_t size) } // Loop until every byte has been sent - int sent = 0; - int sizeToSend = static_cast(size); - for (int length = 0; length < sizeToSend; length += sent) + int result = 0; + for (sent = 0; sent < size; sent += result) { // Send a chunk of data - sent = ::send(getHandle(), static_cast(data) + length, sizeToSend - length, flags); + result = ::send(getHandle(), static_cast(data) + sent, size - sent, flags); // Check for errors - if (sent < 0) - return priv::SocketImpl::getErrorStatus(); + if (result < 0) + { + Status status = priv::SocketImpl::getErrorStatus(); + + if ((status == NotReady) && sent) + return Partial; + + return status; + } } return Done; @@ -294,17 +312,30 @@ Socket::Status TcpSocket::send(Packet& packet) // First convert the packet size to network byte order Uint32 packetSize = htonl(static_cast(size)); - + // Allocate memory for the data block to send std::vector blockToSend(sizeof(packetSize) + size); - + // Copy the packet size and data into the block to send std::memcpy(&blockToSend[0], &packetSize, sizeof(packetSize)); if (size > 0) std::memcpy(&blockToSend[0] + sizeof(packetSize), data, size); // Send the data block - return send(&blockToSend[0], blockToSend.size()); + std::size_t sent; + Status status = send(&blockToSend[0] + packet.m_sendPos, blockToSend.size() - packet.m_sendPos, sent); + + // In the case of a partial send, record the location to resume from + if (status == Partial) + { + packet.m_sendPos += sent; + } + else if (status == Done) + { + packet.m_sendPos = 0; + } + + return status; } -- cgit v1.2.3