Both fr::TcpSocket and fr::SSLSocket can have timeouts specified when connecting. This works by putting the socket into non-blocking mode, making a connect, and then selecting on the socket for the requested timeout. If the select times out then we've failed to connect, if it didn't time out then we've connected.
103 lines
2.9 KiB
C++
103 lines
2.9 KiB
C++
//
|
|
// Created by fred on 06/12/16.
|
|
//
|
|
|
|
#ifndef FRNETLIB_TCPSOCKET_H
|
|
#define FRNETLIB_TCPSOCKET_H
|
|
|
|
#include <memory>
|
|
#include <mutex>
|
|
#include "Socket.h"
|
|
|
|
namespace fr
|
|
{
|
|
class TcpSocket : public Socket
|
|
{
|
|
public:
|
|
TcpSocket() noexcept;
|
|
virtual ~TcpSocket() noexcept;
|
|
TcpSocket(TcpSocket &&other) noexcept
|
|
: socket_descriptor(other.socket_descriptor){}
|
|
void operator=(const TcpSocket &other)=delete;
|
|
|
|
/*!
|
|
* Close the connection.
|
|
*/
|
|
virtual void close_socket();
|
|
|
|
/*!
|
|
* Connects the socket to an address.
|
|
*
|
|
* @param address The address of the socket to connect to
|
|
* @param port The port of the socket to connect to
|
|
* @param timeout The number of seconds to wait before timing the connection attempt out. Pass -1 for default.
|
|
* @return A Socket::Status indicating the status of the operation.
|
|
*/
|
|
virtual Socket::Status connect(const std::string &address, const std::string &port, std::chrono::seconds timeout) override;
|
|
|
|
/*!
|
|
* Sets the socket file descriptor.
|
|
*
|
|
* @param descriptor The socket descriptor.
|
|
*/
|
|
virtual void set_descriptor(int descriptor);
|
|
|
|
/*!
|
|
* Attempts to send raw data down the socket, without
|
|
* any of frnetlib's framing. Useful for communicating through
|
|
* different protocols.
|
|
*
|
|
* @param data The data to send.
|
|
* @param size The number of bytes, from data to send. Be careful not to overflow.
|
|
* @return The status of the operation.
|
|
*/
|
|
virtual Status send_raw(const char *data, size_t size) override;
|
|
|
|
|
|
/*!
|
|
* Receives raw data from the socket, without any of
|
|
* frnetlib's framing. Useful for communicating through
|
|
* different protocols. This will attempt to read 'data_size'
|
|
* bytes, but might not succeed. It'll return how many bytes were actually
|
|
* read in 'received'.
|
|
*
|
|
* @param data Where to store the received data.
|
|
* @param buffer_size The number of bytes to try and receive. Be sure that it's not larger than data.
|
|
* @param received Will be filled with the number of bytes actually received, might be less than you requested.
|
|
* @return The status of the operation, if the socket has disconnected etc.
|
|
*/
|
|
virtual Status receive_raw(void *data, size_t buffer_size, size_t &received) override;
|
|
|
|
/*!
|
|
* Sets if the socket should be blocking or non-blocking.
|
|
*
|
|
* @param should_block True to block, false otherwise.
|
|
*/
|
|
void set_blocking(bool should_block) override;
|
|
|
|
/*!
|
|
* Gets the unerlying socket descriptor
|
|
*
|
|
* @return The socket descriptor
|
|
*/
|
|
int32_t get_socket_descriptor() const override;
|
|
|
|
/*!
|
|
* Checks to see if we're connected to a socket or not
|
|
*
|
|
* @return True if it's connected. False otherwise.
|
|
*/
|
|
inline bool connected() const final
|
|
{
|
|
return socket_descriptor > -1;
|
|
}
|
|
|
|
protected:
|
|
int32_t socket_descriptor;
|
|
};
|
|
|
|
}
|
|
|
|
|
|
#endif //FRNETLIB_TCPSOCKET_H
|