os_pipe, os_pipe_connection_server


Communication with pipes requires the use of two classes: os_pipe and os_pipe_connection_server . The os_pipe class encapsulates the expected read/write mechanisms and also provides an interface for connecting to pipe servers. As its name implies, the os_pipe_connection_server class is used to service pipe connections. Due to operating system limitations, the os_pipe_connection_server class cannot be used with Microsoft Windows 95 platforms.

The following sequence specifies how communication is established between a client and a server.

  1. The server constructs an os_pipe_connection_server using a predetermined name.
  2. The server creates a detached os_pipe that becomes the endpoint for the final connection.
  3. The server waits for an incoming connection request using accept() . The server then passes accept() a reference to the os_pipe created in step 2 above.
  4. The client creates an os_pipe instance and uses connect_to() to initiate a connection with the server.
  5. The server returns from the call to accept() and a connection is established. Communication can now occur using the low-level read() and write() methods or the pipe can be used with Streaming<ToolKit> for higher-level communication.

After communication is established, the server can issue another accept() command to the connection server and then wait for additional clients. A typical server often spawns a thread to service a client connection; then the server quickly returns to accept another connection.

The following examples illustrate a multithreaded client/server arrangement. The server program creates a pipe server and accepts clients. Each client connection is handled by an independent thread allowing simultaneous multiple-client attachments to the server.

Example <ospace/pipe/examples/pipe1s.cpp>
// The server process.

#include <iostream>
#include <ospace/pipe.h>
#include <ospace/thread.h>

void*
response( void* arg )
  {
  os_pipe* pipe = (os_pipe*) arg;
  char buffer[ 100 ];
  int result = pipe->read( buffer, sizeof( buffer ) );
  buffer[ result ] = 0; // Null terminate result.
  cout << "Server read: " << buffer << endl;
  os_this_thread::sleep( 5 );
  cout << "Server sends: " << buffer << endl;
  pipe->write( buffer, result );
  delete pipe;
  return 0;
  }

void
main()
  {
  os_pipe_toolkit init_pipe;
  os_thread_toolkit init_thread;

  cout << "Server started." << endl;
  os_pipe_connection_server server( "server_pipe" );

  while( true )
    {
    os_pipe* pipe = new os_pipe;
    server.accept( *pipe );
    cout << "Server accepted connection" << endl;

    // Create a detached thread to service the connection.
    os_thread dispatch( response, (void*) pipe, 0, true );
    }
  }

Server started.
Server accepted connection
Server read: hello
Server accepted connection
Server read: hello
Server sends: hello
Server sends: hello
Example <ospace/pipe/examples/pipe1c.cpp>
// The client process.

#include <iostream>
#include <ospace/pipe.h>

void
main()
  {
  cout << "Client started." << endl;
  os_pipe pipe;
  pipe.connect_to( "server_pipe" );
  cout << "Client connected." << endl;
  cout << "Client sends: hello" << endl;
  pipe.write( "hello", 5 );

  char buffer[ 100 ];
  int result = pipe.read( buffer, sizeof( buffer ) );
  buffer[ result ] = 0;
  cout << "Client read: " << buffer << endl;
  }

Client started.
Client connected.
Client sends: hello
Client read: hello

Copyright©1994-2026 Recursion Software LLC
All Rights Reserved - For use by licensed users only.