Dr. Dobb's is part of the Informa Tech Division of Informa PLC

This site is operated by a business or businesses owned by Informa PLC and all copyright resides with them. Informa PLC's registered office is 5 Howick Place, London SW1P 1WG. Registered in England and Wales. Number 8860726.


Channels ▼
RSS

Handling Multiple TCP Connections in C++


May 1996/Handling Multiple TCP Connections in C++/Listing 4

Listing 4: Relay loop with a finite state machine


class PacketRelay
{
  StreamSocket& sock1;
  StreamSocket& sock2;

  char sock1_name[80];                  // Socket names for easy reference
  char sock2_name[80];                  // (name cache)

  char * buffer;
  enum { IO_buffer_size=12000 };

  BOOL done;

  static PacketRelay * the_PacketRelay;

  void intr_enable(void);
  void intr_disable(void);
                                // Finite State Machine "Actors"
  enum StatusCode {OK=0, NoData, Eof, Failed};  // what Actors return
  enum SOCK_ID { id_sock1, id_sock2 };
  typedef StatusCode (*Actor)(PacketRelay * _this, const SOCK_ID id);

                                        // Meaning write to another socket  and
                                        // keep the log
  StatusCode relay_socket(const SOCK_ID id);
  BOOL done_loop;
  StatusCode is_loop_done(const SOCK_ID id)    { return done_loop ? Eof : OK; }
  StatusCode set_loop_done(const SOCK_ID id)   { done_loop = TRUE; return OK; }
  StatusCode reset_loop_done(const SOCK_ID id) { done_loop = FALSE; return OK;}
  StatusCode set_finished(const SOCK_ID id)    { done = TRUE; return OK;}
                                // Relay Finite State Machine
  struct FSMAction { Actor   actor;
                     SOCK_ID socket_to_use;
                     short   next_state[Eof+1]; };
  static FSMAction FSMProgram [];

public:
  PacketRelay(StreamSocket& _sock1, StreamSocket& _sock2);
  ~PacketRelay(void);
  BOOL q_done(void) const       { return done; }
  static int relay(void);               // That's what relays (if anything)
};

PacketRelay * PacketRelay::the_PacketRelay = 0;

                                // Here is the FSM relay program
PacketRelay::FSMAction PacketRelay::FSMProgram [] =
{
 /* 0 */ {0,    id_sock1,       {0,0,0}},       // Dummy (stop) state

//  State       What to do     on which socket   OK ND EOF
 /* 1 */ { (Actor)&relay_socket,  id_sock1,     {2,  3,  5} },  // start state
 /* 2 */ { (Actor)&relay_socket,  id_sock2,     {1,  4,  6} },
 /* 3 */ { (Actor)&set_loop_done, id_sock1,     {2, -1, -1} },
 /* 4 */ { (Actor)&is_loop_done,  id_sock1,     {1,  0,  0} },
 /* 5 */ { (Actor)&relay_socket,  id_sock2,     {5,  7,  7} },
 /* 6 */ { (Actor)&relay_socket,  id_sock1,     {6,  7,  7} },
 /* 7 */ { (Actor)&set_finished,  id_sock1,     {0,  0,  0} }
};

                                    // This is where it relays: the Finite
                                    // State Machine
                                    // Start with the state #1, do the action and
                                    // pick up the next state based on the action's
                                    // return code. Keep doing it until hit the
                                    // stop state (pc=0)
int PacketRelay::relay(void)
{
  PacketRelay& me = *the_PacketRelay;
  if( me.done )
    return 0;

  int pc;                           // "Program" counter
  for(pc=1; pc != 0; )
  {
    assert( pc > 0 );
    const FSMAction& action = FSMProgram[pc];
    StatusCode result = action.actor(&me,action.socket_to_use);
    if( result == Failed )
      return me.done = TRUE, 0;
    pc = action.next_state[result];
  }
  return 0;
}

//End of File

Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.