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
|
// $Id: CPP-unserver.cpp 91671 2010-09-08 18:39:23Z johnnyw $
// This example tests the features of the ACE_LSOCK_Acceptor and
// ACE_LSOCK_Stream classes. If the platform supports threads it uses
// a thread-per-request concurrency model.
#include "ace/LSOCK_Acceptor.h"
#include "ace/Thread_Manager.h"
#include "ace/OS_main.h"
#include "ace/OS_NS_unistd.h"
#if !defined (ACE_LACKS_UNIX_DOMAIN_SOCKETS)
// Are we running verbosely?
static int verbose = 1;
// Entry point into the server task.
static void *
server (void *arg)
{
ACE_UNIX_Addr cli_addr;
ACE_LSOCK_Stream new_stream;
ACE_HANDLE handle = (ACE_HANDLE) (long) arg;
new_stream.set_handle (handle);
// Make sure we're not in non-blocking mode.
if (new_stream.disable (ACE_NONBLOCK) == -1)
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("%p\n"),
ACE_TEXT ("disable")),
0);
if (new_stream.get_remote_addr (cli_addr) == -1)
ACE_ERROR ((LM_ERROR,
ACE_TEXT ("%p\n"),
ACE_TEXT ("get_remote_addr")));
ACE_DEBUG ((LM_DEBUG,
ACE_TEXT ("(%P|%t) client connected from %C\n"),
cli_addr.get_path_name ()));
// Read data from client (terminate on error).
for (;;)
{
char buf[BUFSIZ];
ssize_t r_bytes = new_stream.recv (buf, sizeof buf);
if (r_bytes == -1)
{
ACE_ERROR ((LM_ERROR,
ACE_TEXT ("%p\n"),
ACE_TEXT ("recv")));
break;
}
else if (r_bytes == 0)
{
ACE_DEBUG ((LM_DEBUG,
ACE_TEXT ("(%P|%t) reached end of input, connection closed by client\n")));
break;
}
else if (verbose && ACE::write_n (ACE_STDOUT, buf, r_bytes) != r_bytes)
ACE_ERROR ((LM_ERROR,
ACE_TEXT ("%p\n"),
ACE_TEXT ("ACE::write_n")));
else if (new_stream.send_n (buf, r_bytes) != r_bytes)
ACE_ERROR ((LM_ERROR,
ACE_TEXT ("%p\n"),
ACE_TEXT ("send_n")));
}
// Close new endpoint (listening endpoint stays open).
if (new_stream.close () == -1)
ACE_ERROR ((LM_ERROR,
ACE_TEXT ("%p\n"),
ACE_TEXT ("close")));
return 0;
}
static int
run_event_loop (const ACE_TCHAR rendezvous[])
{
ACE_LSOCK_Acceptor peer_acceptor;
// Create a server address.
ACE_UNIX_Addr server_addr (rendezvous);
ACE_OS::unlink (rendezvous);
// Create a server.
if (peer_acceptor.open (server_addr) == -1)
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("%p\n"),
ACE_TEXT ("open")),
1);
else if (peer_acceptor.get_local_addr (server_addr) == -1)
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("%p\n"),
ACE_TEXT ("get_local_addr")),
-1);
ACE_DEBUG ((LM_DEBUG,
ACE_TEXT ("starting server %C\n"),
server_addr.get_path_name ()));
// Keep these guys out here to prevent excessive constructor
// calls...
ACE_LSOCK_Stream new_stream;
// Performs the iterative server activities.
for (;;)
{
ACE_Time_Value timeout (ACE_DEFAULT_TIMEOUT);
if (peer_acceptor.accept (new_stream, 0, &timeout) == -1)
{
ACE_ERROR ((LM_ERROR,
ACE_TEXT ("%p\n"),
ACE_TEXT ("accept")));
continue;
}
#if defined (ACE_HAS_THREADS)
if (ACE_Thread_Manager::instance ()->spawn ((ACE_THR_FUNC) server,
reinterpret_cast<void *> (new_stream.get_handle ()),
THR_DETACHED) == -1)
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("(%P|%t) %p\n"),
ACE_TEXT ("spawn")),
1);
#else
server (reinterpret_cast<void *> (new_stream.get_handle ()));
#endif /* ACE_HAS_THREADS */
}
ACE_NOTREACHED (return 0;)
}
int
ACE_TMAIN (int argc, ACE_TCHAR *argv[])
{
return run_event_loop (argc > 1 ? argv[1] : ACE_DEFAULT_RENDEZVOUS);
}
#else
int ACE_TMAIN (int, ACE_TCHAR *[])
{
ACE_ERROR_RETURN ((LM_ERROR,
"this platform does not support UNIX-domain sockets\n"), -1);
}
#endif /* ACE_LACKS_UNIX_DOMAIN_SOCKETS */
|