ACE/FAQ/APG/Sockets
Материал из Wiki.crossplatform.ru
Содержание |
[править] Basic
// $Id: Basic.cpp 80826 2008-03-04 14:51:23Z wotte $ #include "ace/INET_Addr.h" #include "ace/SOCK_Stream.h" #include "ace/SOCK_Connector.h" #include "ace/Log_Msg.h" #include "ace/OS_NS_unistd.h" int ACE_TMAIN (int, ACE_TCHAR *[]) { // Listing 1 code/ch06 ACE_INET_Addr srvr (50000, ACE_LOCALHOST); // Listing 1 // Listing 2 code/ch06 ACE_SOCK_Connector connector; ACE_SOCK_Stream peer; if (-1 == connector.connect (peer, srvr)) ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("connect")), 1); // Listing 2 ssize_t bc; char buf[64]; // Listing 3 code/ch06 peer.send_n ("uptime\n", 7); bc = peer.recv (buf, sizeof(buf)); ACE_OS::write (ACE_STDOUT, buf, bc); peer.close (); // Listing 3 return (0); }
[править] Basic Robust
// $Id: Basic_Robust.cpp 80826 2008-03-04 14:51:23Z wotte $ #include "ace/OS_NS_errno.h" #include "ace/INET_Addr.h" #include "ace/SOCK_Stream.h" #include "ace/SOCK_Connector.h" #include "ace/Log_Msg.h" #include "ace/Time_Value.h" int ACE_TMAIN (int, ACE_TCHAR *[]) { /* * Here we will use the default ctor and the set() * method to configure it. After each set() we will * display the address as a string and then connect * to each respective server. We can reuse the addr * instance once connection has been established. * // Listing 1 code/ch06 ACE_INET_Addr addr; ... addr.set ("HAStatus", ACE_LOCALHOST); ... addr.set ("HALog", ACE_LOCALHOST); // Listing 1 * */ ACE_INET_Addr addr; ACE_TCHAR peerAddress[64]; // Listing 2 code/ch06 addr.set (ACE_TEXT("HAStatus"), ACE_LOCALHOST); if (addr.addr_to_string (peerAddress, sizeof(peerAddress), 0) == 0) { ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P|%t) Connecting to %s\n"), peerAddress)); } // Listing 2 // Listing 3 code/ch06 ACE_SOCK_Stream status; ACE_OS::last_error(0); ACE_SOCK_Connector statusConnector (status, addr); if (ACE_OS::last_error()) ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("status")), 100); // Listing 3 addr.set (ACE_TEXT("HALog"), ACE_LOCALHOST); if (addr.addr_to_string (peerAddress, sizeof(peerAddress), 0) == 0) { ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P|%t) Connecting to %s\n"), peerAddress )); } // Listing 4 code/ch06 ACE_SOCK_Connector logConnector; ACE_Time_Value timeout (10); ACE_SOCK_Stream log; if (logConnector.connect (log, addr, &timeout) == -1) { if (ACE_OS::last_error() == ETIME) { ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P|%t) Timeout while ") ACE_TEXT ("connecting to log server\n"))); } else { ACE_ERROR ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("log"))); } return (101); } // Listing 4 /* * We generally let the OS pick our local port number but * if you want, you can choose that also: // Listing 5 code/ch06 ACE_SOCK_Connector logConnector; ACE_INET_Addr local (4200, ACE_LOCALHOST); if (logConnector.connect (log, addr, 0, local) == -1) { ... // Listing 5 } */ char buf[64]; // Listing 6 code/ch06 ACE_Time_Value sendTimeout (0, 5); if (status.send_n ("uptime\n", 7, &sendTimeout) == -1) { if (ACE_OS::last_error() == ETIME) { ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P|%t) Timeout while sending ") ACE_TEXT ("query to status server\n"))); } // Listing 6 else { ACE_ERROR ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("send_n"))); } return (102); } // Listing 7 code/ch06 ssize_t bc ; ACE_Time_Value recvTimeout (0, 1); if ((bc = status.recv (buf, sizeof(buf), &recvTimeout)) == -1) { ACE_ERROR ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("recv"))); return (103); } log.send_n (buf, bc); // Listing 7 status.close (); log.close (); return (0); }
[править] Iovec
// $Id: Iovec.cpp 80826 2008-03-04 14:51:23Z wotte $ #include "ace/INET_Addr.h" #include "ace/SOCK_Stream.h" #include "ace/SOCK_Connector.h" #include "ace/Log_Msg.h" #include "ace/OS_NS_unistd.h" const char *UPTIME = "uptime"; const char *HUMIDITY = "humidity"; const char *TEMPERATURE = "temperature"; void addCommand (iovec [], const char *) {} int ACE_TMAIN (int, ACE_TCHAR *[]) { ACE_INET_Addr srvr (50000, ACE_LOCALHOST); ACE_SOCK_Connector connector; ACE_SOCK_Stream peer; ACE_ASSERT (connector.connect (peer, srvr) != -1); ssize_t bc; // Listing 1 code/ch06 iovec send[4]; send[0].iov_base = const_cast<char *> ("up"); send[0].iov_len = 2; send[1].iov_base = const_cast<char *> ("time"); send[1].iov_len = 4; send[2].iov_base = const_cast<char *> ("\n"); send[2].iov_len = 1; peer.sendv (send, 3); // Listing 1 // // A more clever approach would use something like this: // Where the addCommand() method allocates and populates // the query array from a set of global commands. // // Listing 2 code/ch06 iovec query[3]; addCommand (query, UPTIME); addCommand (query, HUMIDITY); addCommand (query, TEMPERATURE); peer.sendv (query, 3); // Listing 2 // Listing 3 code/ch06 iovec receive[2]; receive[0].iov_base = new char [32]; receive[0].iov_len = 32; receive[1].iov_base = new char [64]; receive[1].iov_len = 64; bc = peer.recvv (receive, 2); // Listing 3 // Listing 4 code/ch06 for (int i = 0; i < 2 && bc > 0; ++i) { size_t wc = receive[i].iov_len; if (static_cast<size_t> (bc) < wc) wc = static_cast<size_t> (bc); ACE_OS::write (ACE_STDOUT, receive[i].iov_base, wc); bc -= receive[i].iov_len; delete [] (reinterpret_cast<char *> (receive[i].iov_base)); } // Listing 4 // Listing 5 code/ch06 peer.send_n ("uptime\n", 7); iovec response; peer.recvv (&response); ACE_OS::write (ACE_STDOUT, response.iov_base, response.iov_len); delete [] reinterpret_cast<char *> (response.iov_base); // Listing 5 peer.close (); return (0); }
[править] Server
// $Id: Server.cpp 80826 2008-03-04 14:51:23Z wotte $ #include "ace/os_include/os_netdb.h" #include "ace/OS_NS_errno.h" #include "ace/INET_Addr.h" #include "ace/SOCK_Stream.h" #include "ace/SOCK_Acceptor.h" #include "ace/Log_Msg.h" #include "ace/Time_Value.h" int ACE_TMAIN (int, ACE_TCHAR *[]) { // Listing 1 code/ch06 ACE_INET_Addr port_to_listen ("HAStatus"); ACE_SOCK_Acceptor acceptor; if (acceptor.open (port_to_listen, 1) == -1) ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("acceptor.open")), 100); // Listing 1 //FUZZ: disable check_for_lack_ACE_OS /* * The complete open signature: * // Listing 2 code/ch06 int open (const ACE_Addr &local_sap, int reuse_addr = 0, int protocol_family = PF_INET, int backlog = ACE_DEFAULT_BACKLOG, int protocol = 0); // Listing 2 * */ //FUZZ: enable check_for_lack_ACE_OS while (1) { ACE_SOCK_Stream peer; ACE_INET_Addr peer_addr; ACE_Time_Value timeout (10, 0); /* * Basic acceptor usage */ #if 0 // Listing 3 code/ch06 if (acceptor.accept (peer) == -1) ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("(%P|%t) Failed to accept ") ACE_TEXT ("client connection\n")), 100); // Listing 3 #endif /* 0 */ // Listing 4 code/ch06 if (acceptor.accept (peer, &peer_addr, &timeout, 0) == -1) { if (ACE_OS::last_error() == EINTR) ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P|%t) Interrupted while ") ACE_TEXT ("waiting for connection\n"))); else if (ACE_OS::last_error() == ETIMEDOUT) ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P|%t) Timeout while ") ACE_TEXT ("waiting for connection\n"))); } // Listing 4 // Listing 5 code/ch06 else { ACE_TCHAR peer_name[MAXHOSTNAMELEN]; peer_addr.addr_to_string (peer_name, MAXHOSTNAMELEN); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P|%t) Connection from %s\n"), peer_name)); // Listing 5 // Listing 7 code/ch06 char buffer[4096]; ssize_t bytes_received; while ((bytes_received = peer.recv (buffer, sizeof(buffer))) != -1) { peer.send_n (buffer, bytes_received); } peer.close (); // Listing 7 } } ACE_NOTREACHED (return 0); }