summaryrefslogtreecommitdiff
path: root/examples/IPC_SAP/ATM_SAP/CPP-client.cpp
blob: b14cf4870e819609f185c7a05c86315e5c1215ef (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
// $Id$

#include "ace/ATM_Connector.h"
#include "ace/ATM_Addr.h"
#include "ace/High_Res_Timer.h"

ACE_RCSID(ATM_SAP, CPP_client, "$Id$")

#if defined (ACE_HAS_ATM)

#define MAX_LEAVES  32

/* ACE_ATM Client */

int main (int argc, char *argv[])                       
{
  if ( argc < 2 )
    ACE_ERROR_RETURN ((LM_ERROR, 
                       "Usage: %s <rate> <PDU> <session> <host> <selector> [ host sel ] ...\n"
                       "\tUse 0 for default values\n",
                       argv[0]),
                      1);
  
  int rate = ACE_OS::atoi( argv[ 1 ]);
  rate = ( rate != 0 ) ? rate : 170000;
  int pdu_size = ACE_OS::atoi( argv[ 2 ]) * 1024;
  pdu_size = ( pdu_size != 0 ) ? pdu_size : 8192;
  int session = ACE_OS::atoi( argv[ 3 ]);
  session = ( session != 0 ) ? session : 100;

  ACE_OS::printf( "ATM_Client: rate: %d c/s, PDU: %dB, session: %d pkts\n", 
    rate, pdu_size, session );

  // Record all hosts/selectors
  ACE_ATM_Addr hosts[ MAX_LEAVES ];
  int num_leaves = argc / 2 - 2;

  ACE_OS::printf( "ATM_Client: Connecting to ...\n" );
  for ( int i = 0; i < num_leaves; i++ ) {
    hosts[ i ].set( argv[ i*2 + 4 ], 
                    ( argv[ i*2 + 5 ] != 0 ) 
                      ? ACE_OS::atoi( argv[ i*2 + 5 ]) : ACE_ATM_Addr::DEFAULT_SELECTOR );
    ACE_OS::printf( "ATM_Client: leaf: %s (%s), sel: %d\n", 
                    argv[ i*2 + 4 ],
                    hosts[ i ].addr_to_string(), 
                    hosts[ i ].get_selector());
  }

  // The timeout really gets ignored since FORE's drivers don't work when
  //  ioctl or fcntl calls are made on the transport id/file descriptor
  int timeout = ACE_DEFAULT_TIMEOUT;
  char buf[BUFSIZ];
  ACE_ATM_Stream atm_stream;

  char hostname[ MAXNAMELEN ];
  ACE_OS::hostname( hostname, MAXNAMELEN );
  ACE_ATM_Addr local_addr( hostname, hosts[ 0 ].get_selector());

  ACE_OS::printf( "ATM_Client: local host: %s(%s)\n", 
    hostname, local_addr.addr_to_string());

  // In order to construct connections options the file handle is
  // needed.  Therefore, we need to open the ATM_Stream before we
  // construct the options.
  ACE_OS::printf( "ATM_Client: to open a stream\n" );
  if (atm_stream.open () == -1)
    ACE_ERROR_RETURN ((LM_ERROR,
                       "%p\n",
                       "open failed"),
                      1);

  ACE_DEBUG ((LM_DEBUG,
              "ATM_Client: starting non-blocking connection\n"));

  // Initiate timed, non-blocking connection with server.
  ACE_ATM_Connector con;

  // Construct QoS options - currently FORE only supports bandwidth
  ACE_OS::printf( "ATM_Client: specify cell rate at %d c/s\n", rate );
  ACE_ATM_QoS qos; 
  qos.set_rate(atm_stream.get_handle (),
               rate,
               ACE_ATM_QoS::OPT_FLAGS_CPID);

  if ( num_leaves == 1 ) {
    // Point-to-point connection
    // Not sure why but reuse_addr set to true/1 causes problems for
    // FORE/XTI/ATM - this is now handled in ACE_ATM_Connector::connect()
    ACE_OS::printf( "ATM_Client: to open a connection \n" );
    ACE_ATM_Params params = ACE_ATM_Params();
    if (con.connect (atm_stream,
                     hosts[ 0 ],
                     params,
                     qos,
                     (ACE_Time_Value *) &ACE_Time_Value::zero,
                     local_addr,
                     0,
                     0 ) == -1) {
      if (errno != EWOULDBLOCK)
	      ACE_ERROR_RETURN ((LM_ERROR,
                          "%p\n",
                          "ATM_Client: connection failed"),
                          1);

      ACE_DEBUG ((LM_DEBUG,
                    "ATM_Client: starting timed connection\n"));

      // Check if non-blocking connection is in progress, and wait up
      // to timeout seconds for it to complete.
      ACE_Time_Value tv (timeout);

      ACE_OS::printf( "ATM_Client: connection completed\n" );
      if (con.complete (atm_stream,
                        &hosts[ 0 ],
                        &tv) == -1)
		    ACE_ERROR_RETURN ((LM_ERROR,
                          "%p\n",
                          "ATM_Client: connection failed"),
                          1);
      else
		    ACE_DEBUG ((LM_DEBUG,
                   "ATM_Client: connected to %s\n", 
		               hosts[ 0 ].addr_to_string()));
    }
  } else {
    // Point-to-multipoint connection
    for ( int i = 0; i < num_leaves; i++ ) {
      con.add_leaf( atm_stream,
                    hosts[ i ],
                    i,
                    NULL );

    }
  } /* if num_leaves == 1 */
 
  ACE_UINT16 vpi, vci;
  atm_stream.get_vpi_vci(vpi, vci);
  ACE_DEBUG ((LM_DEBUG,
              "ATM_Client: connected to VPI %d VCI %d\n",
              vpi, vci));

  // Send data to server (correctly handles "incomplete writes").

  int s_bytes;
  int total;
  int xmit = 0;
  ACE_High_Res_Timer timer;
  ACE_Time_Value elapsed;
  double real_time;
  double actual_rate;

  for ( ;; ) {
    total = 0;

    timer.start_incr();

    for ( ;; ) {
      s_bytes = atm_stream.send_n( buf, BUFSIZ, 0 );
      if ( s_bytes == -1 )
        ACE_ERROR_RETURN ((LM_ERROR,
                           "%p\n",
                           "send_n"),
                           1);

      total += s_bytes;

      if ( total >= session * pdu_size )
        break;
    }

    timer.stop_incr();
    timer.elapsed_time_incr( elapsed );
    real_time = elapsed.sec() * ACE_ONE_SECOND_IN_USECS + elapsed.usec();
    xmit += total;
    actual_rate = ( double )xmit * ( double )8 / real_time;

    ACE_DEBUG ((LM_DEBUG,
                ASYS_TEXT ("(%t) bytes = %d, usec = %f, rate = %0.00f Mbps\n"),
                xmit,
                real_time,
                actual_rate < 0 ? 0 : actual_rate ));
  }

  // Explicitly close the connection.
  ACE_OS::printf( "ATM_Client: close connection\n" );
  if (atm_stream.close () == -1) 
    ACE_ERROR_RETURN ((LM_ERROR,
                       "%p\n",
                       "close"),
                       -1);
  return 0;
}                                                       
#else
int main (int, char *[])
{
  ACE_ERROR_RETURN ((LM_ERROR, 
		     "your platform isn't configured to support ATM\n"),
                    1);
}
#endif /* ACE_HAS_ATM */