From 3de58bfef4594dab9b014dc3c39bde055bd88d16 Mon Sep 17 00:00:00 2001 From: Zachariah Brown Date: Sun, 22 Mar 2015 07:01:05 -0400 Subject: [PATCH] Added support for patial TCP sends --- include/SFML/Network/SocketStatus.h | 1 + include/SFML/Network/TcpSocket.h | 22 ++++++++++++++++++++++ src/SFML/Network/TcpSocket.cpp | 9 +++++++++ 3 files changed, 32 insertions(+) diff --git a/include/SFML/Network/SocketStatus.h b/include/SFML/Network/SocketStatus.h index 875aca6..49d4321 100644 --- a/include/SFML/Network/SocketStatus.h +++ b/include/SFML/Network/SocketStatus.h @@ -34,6 +34,7 @@ typedef enum { sfSocketDone, ///< The socket has sent / received the data sfSocketNotReady, ///< The socket is not ready to send / receive data yet + sfSocketPartial, ///< The socket sent a part of the data sfSocketDisconnected, ///< The TCP socket has been disconnected sfSocketError ///< An unexpected error happened diff --git a/include/SFML/Network/TcpSocket.h b/include/SFML/Network/TcpSocket.h index 7b69d80..7f549a4 100644 --- a/include/SFML/Network/TcpSocket.h +++ b/include/SFML/Network/TcpSocket.h @@ -150,6 +150,9 @@ CSFML_NETWORK_API void sfTcpSocket_disconnect(sfTcpSocket* socket); //////////////////////////////////////////////////////////// /// \brief Send raw data to the remote peer of a TCP socket /// +/// To be able to handle partial sends over non-blocking +/// sockets, use the sfTcpSocket_sendPartial(sfTcpSocket*, const void*, std::size_t, size_t*) +/// overload instead. /// This function will fail if the socket is not connected. /// /// \param socket TCP socket object @@ -161,6 +164,21 @@ CSFML_NETWORK_API void sfTcpSocket_disconnect(sfTcpSocket* socket); //////////////////////////////////////////////////////////// CSFML_NETWORK_API sfSocketStatus sfTcpSocket_send(sfTcpSocket* socket, const void* data, size_t size); +//////////////////////////////////////////////////////////// +/// \brief Send raw data to the remote peer +/// +/// This function will fail if the socket is not connected. +/// +/// \param socket TCP socket object +/// \param data Pointer to the sequence of bytes to send +/// \param size Number of bytes to send +/// \param sent The number of bytes sent will be written here +/// +/// \return Status code +/// +//////////////////////////////////////////////////////////// +CSFML_NETWORK_API sfSocketStatus sfTcpSocket_sendPartial(sfTcpSocket* socket, const void* data, size_t size, size_t* sent); + //////////////////////////////////////////////////////////// /// \brief Receive raw data from the remote peer of a TCP socket /// @@ -181,6 +199,10 @@ CSFML_NETWORK_API sfSocketStatus sfTcpSocket_receive(sfTcpSocket* socket, void* //////////////////////////////////////////////////////////// /// \brief Send a formatted packet of data to the remote peer of a TCP socket /// +/// In non-blocking mode, if this function returns sfSocketPartial, +/// you must retry sending the same unmodified packet before sending +/// anything else in order to guarantee the packet arrives at the remote +/// peer uncorrupted. /// This function will fail if the socket is not connected. /// /// \param socket TCP socket object diff --git a/src/SFML/Network/TcpSocket.cpp b/src/SFML/Network/TcpSocket.cpp index c3d64b9..ed1a674 100644 --- a/src/SFML/Network/TcpSocket.cpp +++ b/src/SFML/Network/TcpSocket.cpp @@ -115,6 +115,15 @@ sfSocketStatus sfTcpSocket_send(sfTcpSocket* socket, const void* data, size_t si } +//////////////////////////////////////////////////////////// +sfSocketStatus sfTcpSocket_sendPartial(sfTcpSocket* socket, const void* data, size_t size, size_t* sent) +{ + CSFML_CHECK_RETURN(socket, sfSocketError); + + return static_cast(socket->This.send(data, size, *sent)); +} + + //////////////////////////////////////////////////////////// sfSocketStatus sfTcpSocket_receive(sfTcpSocket* socket, void* data, size_t maxSize, size_t* sizeReceived) {