next up previous contents index
Next: Some Useful Functions ( Up: Simple Data Types and Previous: Sockets ( leda_socket )   Contents   Index


Socket Streambuffer ( socket_streambuf )

Definition

An instance sb of class socket_streambuf can be used as an adapter: It turns a leda_socket s into a C++-streambuf object. This object can be used in standard C++ ostreams and istreams to make the communication through the socket easier. A socket_streambuf can also be applied within an encoding_ostream or a decoding_istream provided by LEDA to send compressed or encrypted data over a socket connection (see Sections encoding_ostream and decoding_istream).
Observe that socket_streambuf itself does not apply cryptography to secure the transmitted data. All data is sent as it is. If you want to secure your data, consider using the class secure_socket_streambuf (see Section secure_socket_streambuf).

If two parties want to use the class socket_streambuf to exchange data they have to do the following. First they establish a connection through leda_sockets. Then each party contructs an instance of the class socket_streambuf which is attached to its socket. This is shown in an example at the end of this manual page.

Every instance sb has an out-buffer where outgoing data is buffered before it is sent through the socket over the internet. In addition it has an in-buffer to store data that has been received through the socket. The user may specify the maximum size of each buffer. The actual size of each buffer is determined in a negotiation between the server and the client at the beginning of the communication. The size of outgoing packets from the server is set to the minimum of the out-buffer size of the server and the in-buffer size of the client. The size of the incoming packets is determined in an analogous way.

#include < LEDA/coding/socket_streambuf.h >

Creation

socket_streambuf sb(leda_socket& s, uint32 out_buf_sz = DefaultBufferSize, uint32 in_buf_sz = DefaultBufferSize, bool send_acknowledge = false)
    creates a sb and attaches it to the socket s. The parameters out_buf_sz and in_buf_sz determine the maximum size of the out-buffer and the in-buffer. send_acknowledge specifies whether an acknowledgement is sent for every received packet.
Precondition The connection between the server and the client must have been established when sb is created.

Operations

The class socket_streambuf inherits most of its operations from the class streambuf that belongs to the C++ standard library. Usually there is no need to call these operations explicitly. (You can find documentation for streambuf at http://www.cplusplus.com)

bool sb.failed() returns whether a failure has occured.

string sb.get_error() returns an error message (if available).

void sb.sputEOF() signals the end of the transmission to the receiving socket, so that it does not wait for further data. (This function is called automatically in the destructor unless it has been called explicitly by the user. If sb is not immediately destroyed after the end of the transmission then you should call sputEOF explicitly, otherwise the receiving party might incur a timeout error.)

bool sb.has_put_EOF() returns whether EOF has already been sent.

bool sb.has_got_EOF() returns whether EOF has already been received.

leda_socket& sb.get_socket() returns the socket to which sb is attached.

uint32 sb.get_outgoing_packet_size()
    returns the (actual) outgoing packet size.

uint32 sb.get_incoming_packet_size()
    returns the (actual) incoming packet size.

bool sb.waits_for_acknowledge()
    returns whether sb expects an acknowledgement for outgoing packets.

bool sb.sends_acknowledge() returns whether sb sends an acknowledgement for incoming packets.

Example

The following example shows how the usage of sb from the server and from the client side. In our example the server sends a string, which is received by the client. (Note that it would also be possible that the client sends and the server receives data.)
In order to add compression to the example simply replace ``ostream'' by ``encoding_ostream<Coder>'' and ``istream'' by ``decoding_istream'' as indicated in the comments.

void socket_example_server(int port)
{
  leda_socket sock;
  sock.set_port(port);

  // open port
  if (! sock.listen()) {
    cerr << sock.get_error() << endl; return;
  }
  for (;;) {
    // establish connection
    if (! sock.accept()) {
      cerr << sock.get_error() << endl; continue;
    }

    // send data
    {
      socket_streambuf sb(sock);
      ostream out(&sb);
      // or: encoding_ostream<PPMIICoder> out(&sb);
      out << "Hello world!" << endl;
    } // destroys sb and calls sb.sputEOF() automatically
  }
}

void socket_example_client(int port, string host)
{
  leda_socket sock;
  sock.set_host(host);
  sock.set_port(port);

  // establish connection
  if (! sock.connect()) {
    cerr << sock.get_error() << endl; return;
  }

  // receive data
  socket_streambuf sb(sock);
  istream in(&sb);
  // or: decoding_istream<PPMIICoder> in(&sb);
  string str;
  str.read_line(in);
  cout << "received: " << str << endl;
}


next up previous contents index
Next: Some Useful Functions ( Up: Simple Data Types and Previous: Sockets ( leda_socket )   Contents   Index
Christian Uhrig 2017-04-07