From 73f2c57a14f773f47c41736baeaf06ced18432ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Lucas=20Golini?= Date: Mon, 6 May 2019 22:16:59 -0300 Subject: [PATCH] Added setSendTimeout and setReceiveTimeout to TcpSocket and UdpSocket. --HG-- branch : dev --- include/eepp/network/socket.hpp | 3 +-- include/eepp/network/tcpsocket.hpp | 8 ++++++++ include/eepp/network/udpsocket.hpp | 8 ++++++++ src/eepp/network/platform/unix/socketimpl.cpp | 14 ++++++++++++++ src/eepp/network/platform/unix/socketimpl.hpp | 9 +++++++++ src/eepp/network/platform/win/socketimpl.cpp | 10 ++++++++++ src/eepp/network/platform/win/socketimpl.hpp | 6 ++++++ src/eepp/network/tcpsocket.cpp | 12 ++++++++++++ src/eepp/network/udpsocket.cpp | 14 ++++++++++++-- 9 files changed, 80 insertions(+), 4 deletions(-) diff --git a/include/eepp/network/socket.hpp b/include/eepp/network/socket.hpp index 23b16c85f..884a95120 100644 --- a/include/eepp/network/socket.hpp +++ b/include/eepp/network/socket.hpp @@ -48,8 +48,7 @@ class EE_API Socket : NonCopyable { bool isBlocking() const; protected : /** @brief Types of protocols that the socket can use */ - enum Type - { + enum Type { Tcp, ///< TCP protocol Udp ///< UDP protocol }; diff --git a/include/eepp/network/tcpsocket.hpp b/include/eepp/network/tcpsocket.hpp index fc16f9f04..e201d9353 100644 --- a/include/eepp/network/tcpsocket.hpp +++ b/include/eepp/network/tcpsocket.hpp @@ -113,6 +113,14 @@ class EE_API TcpSocket : public Socket { ** @see Send */ virtual Status receive(Packet& packet); + /** Set the send timeout. Only callable after connect ( after the socket + ** has been initialized ). */ + void setSendTimeout(SocketHandle sock, const Time& timeout); + + /** Set the receive timeout Only callable after connect ( after the socket + ** has been initialized ). */ + void setReceiveTimeout(SocketHandle sock, const Time& timeout); + private: friend class TcpListener; diff --git a/include/eepp/network/udpsocket.hpp b/include/eepp/network/udpsocket.hpp index 5cf175ab0..27840baba 100644 --- a/include/eepp/network/udpsocket.hpp +++ b/include/eepp/network/udpsocket.hpp @@ -98,6 +98,14 @@ class EE_API UdpSocket : public Socket { ** @return Status code ** @see Send */ Status receive(Packet& packet, IpAddress& remoteAddress, unsigned short& remotePort); + + /** Set the send timeout. Only callable after bind ( after the socket + ** has been initialized ). */ + void setSendTimeout(SocketHandle sock, const Time& timeout); + + /** Set the receive timeout Only callable after bind ( after the socket + ** has been initialized ). */ + void setReceiveTimeout(SocketHandle sock, const Time& timeout); private: // Member data std::vector mBuffer; ///< Temporary buffer holding the received data in Receive(Packet) diff --git a/src/eepp/network/platform/unix/socketimpl.cpp b/src/eepp/network/platform/unix/socketimpl.cpp index 8b175ff1d..c003e0bff 100644 --- a/src/eepp/network/platform/unix/socketimpl.cpp +++ b/src/eepp/network/platform/unix/socketimpl.cpp @@ -57,6 +57,20 @@ Socket::Status SocketImpl::getErrorStatus() { } } +void SocketImpl::setSendTimeout(SocketHandle sock, const Time& timeout) { + struct timeval time; + time.tv_sec = static_cast(timeout.asMicroseconds() / 1000000); + time.tv_usec = static_cast(timeout.asMicroseconds() % 1000000); + setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (const char*)&time, sizeof time); +} + +void SocketImpl::setReceiveTimeout(SocketHandle sock, const Time & timeout) { + struct timeval time; + time.tv_sec = static_cast(timeout.asMicroseconds() / 1000000); + time.tv_usec = static_cast(timeout.asMicroseconds() % 1000000); + setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (const char*)&time, sizeof time); +} + }}} #endif diff --git a/src/eepp/network/platform/unix/socketimpl.hpp b/src/eepp/network/platform/unix/socketimpl.hpp index 0cc0e5f9f..3cf6dbfca 100644 --- a/src/eepp/network/platform/unix/socketimpl.hpp +++ b/src/eepp/network/platform/unix/socketimpl.hpp @@ -5,6 +5,7 @@ #if defined( EE_PLATFORM_POSIX ) +#include #include #include #include @@ -14,6 +15,8 @@ #include #include +using namespace EE::System; + namespace EE { namespace Network { namespace Private { /** @brief Helper class implementing all the non-portable socket stuff; this is the Unix version */ @@ -44,6 +47,12 @@ class SocketImpl { /** Get the last socket error status ** @return Status corresponding to the last socket error */ static Socket::Status getErrorStatus(); + + /** Set the send timeout */ + static void setSendTimeout(SocketHandle sock, const Time& timeout); + + /** Set the receive timeout */ + static void setReceiveTimeout(SocketHandle sock, const Time& timeout); }; }}} diff --git a/src/eepp/network/platform/win/socketimpl.cpp b/src/eepp/network/platform/win/socketimpl.cpp index a773244e3..433f853f0 100644 --- a/src/eepp/network/platform/win/socketimpl.cpp +++ b/src/eepp/network/platform/win/socketimpl.cpp @@ -42,6 +42,16 @@ Socket::Status SocketImpl::getErrorStatus() { } } +void SocketImpl::setSendTimeout(SocketHandle sock, const Time& timeout) { + DWORD time = timeout.asMilliseconds(); + setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (const char*)&time, sizeof time); +} + +void SocketImpl::setReceiveTimeout(SocketHandle sock, const Time & timeout) { + DWORD time = timeout.asMilliseconds(); + setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (const char*)&time, sizeof time); +} + /** Windows needs some initialization and cleanup to get ** sockets working properly... so let's create a class that will do it automatically */ struct SocketInitializer diff --git a/src/eepp/network/platform/win/socketimpl.hpp b/src/eepp/network/platform/win/socketimpl.hpp index ea241cbcd..2a2d2d4bb 100644 --- a/src/eepp/network/platform/win/socketimpl.hpp +++ b/src/eepp/network/platform/win/socketimpl.hpp @@ -47,6 +47,12 @@ class SocketImpl { /** Get the last socket error status ** @return Status corresponding to the last socket error */ static Socket::Status getErrorStatus(); + + /** Set the send timeout */ + static void setSendTimeout(SocketHandle sock, const Time& timeout); + + /** Set the receive timeout */ + static void setReceiveTimeout(SocketHandle sock, const Time& timeout); }; }}} diff --git a/src/eepp/network/tcpsocket.cpp b/src/eepp/network/tcpsocket.cpp index ed1e257b6..b0cfde2b8 100644 --- a/src/eepp/network/tcpsocket.cpp +++ b/src/eepp/network/tcpsocket.cpp @@ -316,6 +316,18 @@ Socket::Status TcpSocket::receive(Packet& packet) { return Done; } +void TcpSocket::setSendTimeout(SocketHandle sock, const Time& timeout) { + if (getHandle() != Private::SocketImpl::invalidSocket()) { + Private::SocketImpl::setSendTimeout(getHandle(), timeout); + } +} + +void TcpSocket::setReceiveTimeout(SocketHandle sock, const Time& timeout) { + if (getHandle() != Private::SocketImpl::invalidSocket()) { + Private::SocketImpl::setReceiveTimeout(getHandle(), timeout); + } +} + TcpSocket::PendingPacket::PendingPacket() : Size (0), SizeReceived(0), diff --git a/src/eepp/network/udpsocket.cpp b/src/eepp/network/udpsocket.cpp index 0dcf8a7ac..0f9883975 100644 --- a/src/eepp/network/udpsocket.cpp +++ b/src/eepp/network/udpsocket.cpp @@ -61,8 +61,7 @@ Socket::Status UdpSocket::send(const void* data, std::size_t size, const IpAddre create(); // Make sure that all the data will fit in one datagram - if (size > MaxDatagramSize) - { + if (size > MaxDatagramSize) { eePRINTL( "Cannot send data over the network (the number of bytes to send is greater than UdpSocket::MaxDatagramSize)" ); return Error; } @@ -143,5 +142,16 @@ Socket::Status UdpSocket::receive(Packet& packet, IpAddress& remoteAddress, unsi return status; } +void UdpSocket::setSendTimeout(SocketHandle sock, const Time& timeout) { + if (getHandle() != Private::SocketImpl::invalidSocket()) { + Private::SocketImpl::setSendTimeout(getHandle(), timeout); + } +} + +void UdpSocket::setReceiveTimeout(SocketHandle sock, const Time& timeout) { + if (getHandle() != Private::SocketImpl::invalidSocket()) { + Private::SocketImpl::setReceiveTimeout(getHandle(), timeout); + } +} }}