Sock submodule for TCP. More...
Sock submodule for TCP.
First you need to include a module that implements this API in your application's Makefile. For example the implementation for GNRC is called gnrc_sock_tcp
.
Above you see a simple TCP echo server. Don't forget to also include the IPv6 module of your networking implementation (e.g. gnrc_ipv6_default
for Generic (GNRC) network stack GNRC) and at least one network device.
After including header files for the address families and the TCP `sock`s and `queue`s themselves, we create an array of sock objects sock_queue
as our listen queue (for simplicity of length 1 in our example) and some buffer space buf
to store the data received by the server:
We want to listen for incoming connections on a specific port, so we set a local end point with that port (12345
in this case).
We then proceed to creating the listen queue queue
. Since it is bound to local
it waits for incoming connections to port 12345
. We don't need any further configuration so we set the flags to 0. In case of an error we stop the program:
The application then waits indefinitely for an incoming connection with sock_tcp_accept()
. If we want to timeout this wait period we could alternatively set the timeout
parameter of sock_tcp_accept() to a value != SOCK_NO_TIMEOUT. If an error occurs during that we print an error message but proceed waiting.
On successful connection establishment with a client we get a connected sock
object and we try to read the incoming stream into buf
using sock_tcp_read()
on that sock
. Again, we could use another timeout period than SOCK_NO_TIMEOUT with this function. If we error we break the read loop and disconnect the sock
.
Otherwise, we print the received message and write it back to the connected sock
(an again breaking the loop on error).
In the case of we somehow manage to break the infinite accepting loop we stop the listening queue appropriately.
Above you see a simple TCP echo client. Again: Don't forget to also include the IPv6 module of your networking implementation (e.g. gnrc_ipv6_default
for GNRC) and at least one network device. Ad0)ditionally, for the IPv6 address parsing you need the IPv6 address module.
This time instead of creating a listening queue we create a connected sock
object directly. To connect it to a port at a host we setup a remote end-point first (with port 12345
and address fe80::d8fa:55ff:fedf:4523
in this case; your IP address may differ of course) and connect to it using sock_tcp_connect()
. We neither care about the local port nor additional configuration so we set both the local_port
and flags
parameter of sock_tcp_connect()
to 0
:
On error we just terminate the program, on success we send a message (Hello!
) and again terminate the program on error:
Otherwise, we wait for the reply and print it in case of success (and terminate in case of error):
Files | |
file | tcp.h |
TCP sock definitions. | |
Typedefs | |
typedef struct _sock_tl_ep | sock_tcp_ep_t |
An end point for a TCP sock object. | |
typedef struct sock_tcp | sock_tcp_t |
Type for a TCP sock object. More... | |
typedef struct sock_tcp_queue | sock_tcp_queue_t |
Type for a TCP listening queue. More... | |
Functions | |
int | sock_tcp_connect (sock_tcp_t *sock, const sock_tcp_ep_t *remote, uint16_t local_port, uint16_t flags) |
Establishes a new TCP sock connection. More... | |
int | sock_tcp_listen (sock_tcp_queue_t *queue, const sock_tcp_ep_t *local, sock_tcp_t *queue_array, unsigned queue_len, uint16_t flags) |
Listen for an incoming connection request on local end point. More... | |
void | sock_tcp_disconnect (sock_tcp_t *sock) |
Disconnects a TCP connection. More... | |
void | sock_tcp_stop_listen (sock_tcp_queue_t *queue) |
Stops listening on TCP listening queue. More... | |
int | sock_tcp_get_local (sock_tcp_t *sock, sock_tcp_ep_t *ep) |
Gets the local end point of a TCP sock object. More... | |
int | sock_tcp_get_remote (sock_tcp_t *sock, sock_tcp_ep_t *ep) |
Gets the remote end point of a TCP sock object. More... | |
int | sock_tcp_queue_get_local (sock_tcp_queue_t *queue, sock_tcp_ep_t *ep) |
Gets the local end point of a TCP sock queue object. More... | |
int | sock_tcp_accept (sock_tcp_queue_t *queue, sock_tcp_t **sock, uint32_t timeout) |
Receives and handles TCP connection requests from other peers. More... | |
ssize_t | sock_tcp_read (sock_tcp_t *sock, void *data, size_t max_len, uint32_t timeout) |
Reads data from an established TCP stream. More... | |
ssize_t | sock_tcp_write (sock_tcp_t *sock, const void *data, size_t len) |
Writes data to an established TCP stream. More... | |
typedef struct sock_tcp_queue sock_tcp_queue_t |
Type for a TCP listening queue.
struct sock_tcp_queue
needs to be defined by implementation-specific sock_types.h
. typedef struct sock_tcp sock_tcp_t |
int sock_tcp_accept | ( | sock_tcp_queue_t * | queue, |
sock_tcp_t ** | sock, | ||
uint32_t | timeout | ||
) |
Receives and handles TCP connection requests from other peers.
(queue != NULL) && (sock != NULL)
[in] | queue | A TCP listening queue. |
[out] | sock | A new TCP sock object for the established sock object. |
[in] | timeout | Timeout for accept in microseconds. If 0 and no data is available, the function returns immediately. May be SOCK_NO_TIMEOUT for no timeout (wait until data is available). |
timeout
is 0
and no data is available. sock
has been aborted while in this function queue
was not initialized using sock_tcp_listen(). queue
are not permitted on this system (e.g. by firewall rules). int sock_tcp_connect | ( | sock_tcp_t * | sock, |
const sock_tcp_ep_t * | remote, | ||
uint16_t | local_port, | ||
uint16_t | flags | ||
) |
Establishes a new TCP sock connection.
sock != NULL
(remote != NULL) && (remote->port != 0)
[out] | sock | The resulting sock object. |
[in] | remote | Remote end point for the sock object. |
[in] | local_port | Local port for the connection. May be 0. * If local_port == 0 the connection is bound to a random port. |
[in] | flags | Flags for the sock object. See also net_sock_flags. May be 0. |
(flags & SOCK_FLAGS_REUSE_EP) == 0
and local_port
is already used elsewhere remote
is not supported. remote
end point. remote
is an invalid address. remote
is not a valid interface. remote
is not reachable. remote
are not permitted on the system (e.g. by firewall rules). remote
timed out. void sock_tcp_disconnect | ( | sock_tcp_t * | sock | ) |
Disconnects a TCP connection.
sock != NULL
If we want to timeout this wait period we could alternatively set the timeout
parameter of sock_tcp_accept() to a value != SOCK_NO_TIMEOUT.[in] | sock | A TCP sock object. |
int sock_tcp_get_local | ( | sock_tcp_t * | sock, |
sock_tcp_ep_t * | ep | ||
) |
Gets the local end point of a TCP sock object.
(sock != NULL) && (ep != NULL)
[in] | sock | A TCP sock object. |
[out] | ep | The local end point. |
sock
has no local end point. int sock_tcp_get_remote | ( | sock_tcp_t * | sock, |
sock_tcp_ep_t * | ep | ||
) |
Gets the remote end point of a TCP sock object.
(sock != NULL) && (ep != NULL)
[in] | sock | A TCP sock object. |
[out] | ep | The remote end point. |
sock
is not connected to a remote end point. int sock_tcp_listen | ( | sock_tcp_queue_t * | queue, |
const sock_tcp_ep_t * | local, | ||
sock_tcp_t * | queue_array, | ||
unsigned | queue_len, | ||
uint16_t | flags | ||
) |
Listen for an incoming connection request on local
end point.
queue != NULL
(local != NULL) && (local->port != 0)
(queue_array != NULL) && (queue_len != 0)
[in] | queue | The resulting listening queue. |
[in] | local | Local end point to listen on. |
[in] | queue_array | Array of sock objects. |
[in] | queue_len | Length of queue_array . |
[in] | flags | Flags for the listening queue. See also net_sock_flags. May be 0. |
(flags & SOCK_FLAGS_REUSE_EP) == 0
and local
is already used elsewhere local
is not supported. local
is not a valid interface. queue
. int sock_tcp_queue_get_local | ( | sock_tcp_queue_t * | queue, |
sock_tcp_ep_t * | ep | ||
) |
Gets the local end point of a TCP sock queue object.
(sock != NULL) && (ep != NULL)
[in] | queue | A TCP sock queue object. |
[out] | ep | The local end point. |
queue
has no local end point. ssize_t sock_tcp_read | ( | sock_tcp_t * | sock, |
void * | data, | ||
size_t | max_len, | ||
uint32_t | timeout | ||
) |
Reads data from an established TCP stream.
(sock != NULL) && (data != NULL) && (max_len > 0)
[in] | sock | A TCP sock object. |
[out] | data | Pointer where the read data should be stored. |
[in] | max_len | Maximum space available at data . If read data exceeds max_len the data is truncated and the remaining data can be retrieved later on. |
[in] | timeout | Timeout for receive in microseconds. If 0 and no data is available, the function returns immediately. May be SOCK_NO_TIMEOUT for no timeout (wait until data is available). |
timeout
is 0
and no data is available. sock
. sock
is not connected to a remote end point. timeout
expired. void sock_tcp_stop_listen | ( | sock_tcp_queue_t * | queue | ) |
Stops listening on TCP listening queue.
queue != NULL
[in] | queue | A TCP listening queue. |
ssize_t sock_tcp_write | ( | sock_tcp_t * | sock, |
const void * | data, | ||
size_t | len | ||
) |
Writes data to an established TCP stream.
(sock != NULL)
if (len != NULL): (data != NULL)
[in] | sock | A TCP sock object. |
[in] | data | Pointer to the data to be written to the stream. |
[in] | len | Maximum space available at data . |
sock
. data
. sock
is not connected to a remote end point.