nanomsgxx-sockets(7) -- Nanomsgxx Sockets
=========================================

## DESCRIPTION

Sockets are one main component of the nanomsg API, they're used to exchanged
messages between nodes and are reprented by descriptors.  
nanomsgxx uses the nnxx::socket type to wrap around such descriptors and provide
automatic resource management and low level abstractions around the C API socket
routines.

## SEND

The nnxx::socket type has a send member function that lets us send messages
throught a socket, it comes with multiple signatures:

```
class socket {

  // ...

  // Working with any memory buffer.
  int send(const void *b, size_t n, int f, message_control &&c);
  int send(const void *b, size_t n, int f = 0);

  // Working with C-strings.
  int send(const char *s, int f, message_control &&c);
  int send(const char *s, int f = 0);

  // Working with any string-like types.
  template < typename T >
  int send(const T &s, int f, message_control &&c);
  template < typename T >
  int send(const T &s, int f = 0);

  // Zero-copy operations.
  int send(message &&m, int f, message_control &&c);
  int send(message &&m, int f = 0);

  // ...

};
```

As you can see the type of the first argument specifies which version will be
selected by the compiler, and other arguments are always the same:

- optional flags, that may be a combination of `nnxx::DONTWAIT`, `nnxx::NO_SIGNAL_ERROR` and `nnxx::NO_TIMEOUT_ERROR`
- optional `nnxx::message_control` instance providing meta-information to the underlying procotol

The template versions of the send functions accept any type that can be iterated.

The send functions return the number of bytes in the sent messages, or a negative
value under some conditions if the flags argument isn't zero.

## RECEIVE

Receiving messages is just as easy as sending, using the recv member function
that exists with these signatures:

```
class socket {

  // ...

  // Working with any memory buffer.
  int recv(void *buf, size_t len, int flags, message_control &ctl);
  int recv(void *buf, size_t len, int flags = 0);

  // Working with any string-like types.
  template < typename T >
  T recv(int flags, message_control &ctl);
  template < typename T >
  T recv(int flags = 0);

  // Zero-copy operations.
  message recv(int flags, message_control &ctl);
  message recv(nt flags = 0);

  // ...

};
```

As you can see the type of the first argument specifies which version will be
selected by the compiler, and other arguments are always the same:

- optional flags, that may be a combination of `nnxx::DONTWAIT`, `nnxx::NO_SIGNAL_ERROR` and `nnxx::NO_TIMEOUT_ERROR`
- optional `nnxx::message_control` instance where meta-information coming from the underlying protocol will be stored

The first version of recv functions return the number of bytes in the received
message, or a negative value under some conditions if the flags argument isn't
zero.  
The second version is templated, the template argument should be a sequence
container (string, vector, list... ) that accepts two iterators (start and end)
as argument. The third version return an instance `nnxx::message` carying a
memory buffer with a message read from the socket, the object can be evaluated
to false if something happened and the flags argument wasn't zero, for example:

```
nnxx::message msg { s.recv(nnxx::DONTWAIT) };

if (!msg) {
  // Check errno, it's probably be set to EAGAIN because
  // no message could be read from the socket.
  // ...
}
```

## OPTIONS

Options can be set on sockets, some options apply to the socket properties, some
other apply to the underlying protocol. nnxx::socket provides member functions
that wrap around the nn_setsockopt and nn_getsockopt routine:

```
class socket {

  // ...

  void setopt(int lvl, int name, const void *val, size_t len);

  template < typename T >
  void setopt(int lvl, int name, const T &val);

  void getopt(int lvl, int name, void *val, size_t *len) const;

  template < typename T >
  void getopt(int lvl, int name, T &val) const;

  template < typename T >
  T getopt(int lvl, int name) const;

  // ...

};
```

The templated version uses the other one and is a simple wrapper for convenience
so the option type must match the one required by the nanomsg C API.

## SEE ALSO

nnxx::socket(3)  
nanomsgxx(7)  
nanomsg(7)  

## AUTHORS

Achille Roussel
