class EE::Network::TcpSocket

Overview

Specialized socket using the TCP protocol. More…

#include <tcpsocket.hpp>

class TcpSocket: public EE::Network::Socket {
public:
    // typedefs

    typedef std::function<void(const char*bytes, size_t n)> ReadFn;

    // structs

    struct PendingPacket;

    // construction

    virtual ~TcpSocket();

    // methods

    static TcpSocket* New();
    unsigned short getLocalPort() const;
    IpAddress getRemoteAddress() const;
    unsigned short getRemotePort() const;
    virtual Status connect(const IpAddress& remoteAddress, unsigned short remotePort, Time timeout = Time::Zero);
    virtual void disconnect();
    virtual Status send(const void* data, std::size_t size);
    virtual Status send(const void* data, std::size_t size, std::size_t& sent);
    virtual Status receive(void* data, std::size_t size, std::size_t& received);
    virtual Status send(Packet& packet);
    virtual Status receive(Packet& packet);
    void setSendTimeout(SocketHandle sock, const Time& timeout);
    void setReceiveTimeout(SocketHandle sock, const Time& timeout);
    void startAsyncRead(ReadFn readFn = nullptr);
};

Inherited Members

public:
    // enums

    enum {
        AnyPort = 0,
    };

    enum Status;

    // methods

    void setBlocking(bool blocking);
    bool isBlocking() const;

Detailed Documentation

Specialized socket using the TCP protocol.

TCP is a connected protocol, which means that a TCP socket can only communicate with the host it is connected to. It can’t send or receive anything if it is not connected.

The TCP protocol is reliable but adds a slight overhead. It ensures that your data will always be received in order and without errors (no data corrupted, lost or duplicated).

When a socket is connected to a remote host, you can retrieve informations about this host with the GetRemoteAddress and GetRemotePort functions. You can also get the local port to which the socket is bound (which is automatically chosen when the socket is connected), with the GetLocalPort function.

Sending and receiving data can use either the low-level or the high-level functions. The low-level functions process a raw sequence of bytes, and cannot ensure that one call to Send will exactly match one call to Receive at the other end of the socket.

The high-level interface uses packets (see Packet), which are easier to use and provide more safety regarding the data that is exchanged. You can look at the Packet class to get more details about how they work.

The socket is automatically disconnected when it is destroyed, but if you want to explicitely close the connection while the socket instance is still alive, you can call disconnect.

Usage example:

// ----- The client -----

// Create a socket and connect it to 192.168.1.50 on port 55001
TcpSocket socket;
socket.connect("192.168.1.50", 55001);

// Send a message to the connected host
std::string message = "Hi, I am a client";
socket.send(message.c_str(), message.size() + 1);

// Receive an answer from the server
char buffer[1024];
std::size_t received = 0;
socket.receive(buffer, sizeof(buffer), received);
std::cout << "The server said: " << buffer << std::endl;

// ----- The server -----

// Create a listener to wait for incoming connections on port 55001
TcpListener listener;
listener.listen(55001);

// Wait for a connection
TcpSocket socket;
listener.accept(socket);
std::cout << "New client connected: " << socket.getRemoteAddress() << std::endl;

// Receive a message from the client
char buffer[1024];
std::size_t received = 0;
socket.receive(buffer, sizeof(buffer), received);
std::cout << "The client said: " << buffer << std::endl;

// Send an answer
std::string message = "Welcome, client";
socket.send(message.c_str(), message.size() + 1);

See also:

EE::Network::Socket, EE::Network::UdpSocket, EE::Network::Packet

Methods

unsigned short getLocalPort() const

Get the port to which the socket is bound locally If the socket is not connected, this function returns 0.

Returns:

Port to which the socket is bound

See also:

Connect, GetRemotePort

IpAddress getRemoteAddress() const

Get the address of the connected peer It the socket is not connected, this function returns IpAddress::None.

Returns:

Address of the remote peer

See also:

GetRemotePort

unsigned short getRemotePort() const

Get the port of the connected peer to which the socket is connected If the socket is not connected, this function returns 0.

Returns:

Remote port to which the socket is connected

See also:

GetRemoteAddress

virtual Status connect(const IpAddress& remoteAddress, unsigned short remotePort, Time timeout = Time::Zero)

Connect the socket to a remote peer In blocking mode, this function may take a while, especially if the remote peer is not reachable. The last parameter allows you to stop trying to connect after a given timeout. If the socket was previously connected, it is first disconnected.

Parameters:

remoteAddress

Address of the remote peer

remotePort

Port of the remote peer

timeout

Optional maximum time to wait

Returns:

Status code

See also:

Disconnect

virtual void disconnect()

Disconnect the socket from its remote peer This function gracefully closes the connection. If the socket is not connected, this function has no effect.

See also:

Connect

virtual Status send(const void* data, std::size_t size)

Send raw data to the remote peer To be able to handle partial sends over non-blocking sockets, use the send(const void*, std::size_t, std::size_t&) overload instead.

This function will fail if the socket is not connected.

Parameters:

data

Pointer to the sequence of bytes to send

size

Number of bytes to send

Returns:

Status code

See also:

Receive

virtual Status send(const void* data, std::size_t size, std::size_t& sent)

Send raw data to the remote peer This function will fail if the socket is not connected.

Parameters:

data

Pointer to the sequence of bytes to send

size

Number of bytes to send

sent

The number of bytes sent will be written here

Returns:

Status code

See also:

receive

virtual Status receive(void* data, std::size_t size, std::size_t& received)

Receive raw data from the remote peer In blocking mode, this function will wait until some bytes are actually received. This function will fail if the socket is not connected.

Parameters:

data

Pointer to the array to fill with the received bytes

size

Maximum number of bytes that can be received

received

This variable is filled with the actual number of bytes received

Returns:

Status code

See also:

Send

virtual Status send(Packet& packet)

Send a formatted packet of data to the remote peer.

In non-blocking mode, if this function returns sf::Socket::Partial, 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.

Parameters:

packet

Packet to send

Returns:

Status code

See also:

Receive

virtual Status receive(Packet& packet)

Receive a formatted packet of data from the remote peer In blocking mode, this function will wait until the whole packet has been received. This function will fail if the socket is not connected.

Parameters:

packet

Packet to fill with the received data

Returns:

Status code

See also:

Send

void setSendTimeout(SocketHandle sock, const Time& timeout)

Set the send timeout. Only callable after connect ( after the socket has been initialized ).

void setReceiveTimeout(SocketHandle sock, const Time& timeout)

Set the receive timeout Only callable after connect ( after the socket has been initialized ).

void startAsyncRead(ReadFn readFn = nullptr)

Starts a new thread to receive all stdout and stderr data.