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
|
// $Id: CPP-ATM-client.cpp 91671 2010-09-08 18:39:23Z johnnyw $
#include "ace/TLI_Connector.h"
#include "ace/ATM_QoS.h"
#include "ace/ATM_Addr.h"
#include "ace/Log_Msg.h"
#if defined (ACE_HAS_FORE_ATM_XTI)
/* ACE_XTI/ATM Client */
int ACE_TMAIN (int argc, ACE_TCHAR *argv[])
{
if (argc < 2)
ACE_ERROR_RETURN ((LM_ERROR,
"Usage: %s [-s selector] hostname [QoS in KB/sec]\n",
argv[0]),
1);
unsigned char selector = ACE_ATM_Addr::DEFAULT_SELECTOR;
int selector_specified = 0;
extern int optind;
int opt;
while ((opt = ACE_OS::getopt (argc, argv, "s:?h")) != EOF)
{
switch(opt)
{
case 's':
selector = ACE_OS::atoi (optarg);
selector_specified = 1;
break;
case '?':
case 'h':
ACE_ERROR_RETURN ((LM_ERROR,
"Usage: %s hostname [-s selector] [QoS in KB/s]\n",
argv[0]),
1);
} // switch
} // while getopt
const char *host = argv[optind];
int rate = (argc == 3) ? ACE_OS::atoi (argv[2]) :
(argc == 5) ? ACE_OS::atoi (argv[4]) : 0;
// 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_TLI_Stream cli_stream;
ACE_ATM_Addr remote_addr (host);
if (selector_specified)
remote_addr.set_selector(selector);
char hostname[MAXNAMELEN];
ACE_OS::hostname(hostname, MAXNAMELEN);
ACE_ATM_Addr local_addr (hostname);
// In order to construct connections options the file handle is
// needed. Therefore, we need to open the TLI_Stream before we
// construct the options.
if (cli_stream.open (ACE_XTI_ATM_DEVICE, O_RDWR, 0) == -1)
ACE_ERROR_RETURN ((LM_ERROR,
"%p\n",
"open failed"),
1);
ACE_DEBUG ((LM_DEBUG,
"starting non-blocking connect\n"));
// Initiate timed, non-blocking connection with server.
ACE_TLI_Connector con;
// Construct QoS options - currently FORE only supports bandwidth
ACE_ATM_QoS qos;
qos.set_rate(cli_stream.get_handle (),
rate,
ACE_ATM_QoS::OPT_FLAGS_CPID);
struct netbuf optbuf = qos.get_qos();
// long optlen = 0;
// char *options = remote_addr.construct_options (cli_stream.get_handle (),
// rate,
// ACE_ATM_Addr::OPT_FLAGS_CPID,
// &optlen);
// struct netbuf optbuf;
// optbuf.len = optlen;
// optbuf.buf = options;
// Not sure why but reuse_addr set to true/1 causes problems for
// FORE/XTI/ATM - this is now handled in ACE_TLI_Connector::connect()
if (con.connect (cli_stream,
remote_addr,
(ACE_Time_Value *) &ACE_Time_Value::zero,
local_addr,
1,
O_RDWR,
0,
ACE_XTI_ATM_DEVICE,
0,
1,
0,
&optbuf) == -1)
{
if (errno != EWOULDBLOCK)
ACE_ERROR_RETURN ((LM_ERROR,
"%p\n",
"connection failed"),
1);
ACE_DEBUG ((LM_DEBUG,
"starting timed connect\n"));
// Check if non-blocking connection is in progress, and wait up
// to timeout seconds for it to complete.
ACE_Time_Value tv (timeout);
if (con.complete (cli_stream,
&remote_addr,
&tv) == -1)
ACE_ERROR_RETURN ((LM_ERROR,
"%p\n",
"connection failed"),
1);
else
ACE_DEBUG ((LM_DEBUG,
"connected to %s\n",
remote_addr.addr_to_string ()));
}
// Send data to server (correctly handles "incomplete writes").
for (int r_bytes;
(r_bytes = ACE_OS::read (ACE_STDIN, buf, sizeof buf)) > 0;
)
if (cli_stream.send_n (buf,
r_bytes,
0) == -1)
ACE_ERROR_RETURN ((LM_ERROR,
"%p\n",
"send_n"),
1);
// Explicitly close the connection.
if (cli_stream.close () == -1)
ACE_ERROR_RETURN ((LM_ERROR,
"%p\n",
"close"),
-1);
return 0;
}
#else
int ACE_TMAIN (int, ACE_TCHAR *[])
{
ACE_ERROR_RETURN ((LM_ERROR,
"your platform isn't configured to support XTI/ATM\n"),
1);
}
#endif /* ACE_HAS_TLI */
|