diff options
author | James Cowgill <james410@cowgill.org.uk> | 2015-05-08 21:14:39 +0100 |
---|---|---|
committer | James Cowgill <james410@cowgill.org.uk> | 2015-05-08 21:14:39 +0100 |
commit | ebd1b636e5bf0f8fa6d210690582757e8b47f141 (patch) | |
tree | 02dc3aacf1c6f351154432247be0b4347fb14330 /src/SFML/Network/TcpSocket.cpp | |
parent | fa21c65d0c764705cfc377bf0d0de08fac26874e (diff) |
Imported Upstream version 2.3+dfsg
Diffstat (limited to 'src/SFML/Network/TcpSocket.cpp')
-rw-r--r-- | src/SFML/Network/TcpSocket.cpp | 51 |
1 files changed, 41 insertions, 10 deletions
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. @@ -219,6 +219,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<int>(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<const char*>(data) + length, sizeToSend - length, flags); + result = ::send(getHandle(), static_cast<const char*>(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<Uint32>(size)); - + // Allocate memory for the data block to send std::vector<char> 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; } |