本文主要是介绍用ACE实现简易Echo Server,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
一、编写代码
文本查看复制代码打印关于
1. /*
2. * ace_echo_server.cpp
3. *
4. */
5.
6. #include <iostream>
7. #include <string>
8. #include <cctype>
9.
10. #include <ace/INET_Addr.h>
11. #include <ace/SOCK_Stream.h>
12. #include <ace/SOCK_Acceptor.h>
13. #include <ace/Log_Msg.h>
14. #include <ace/Reactor.h>
15. #include <ace/Auto_Ptr.h>
16.
17. using namespace std;
18.
19. class EchoService: public ACE_Event_Handler {
20. public:
21. ACE_SOCK_Stream& peer() {
22. return sock_;
23. }
24.
25. int open() {
26. char peerName[MAXHOSTNAMELEN];
27. ACE_INET_Addr peerAddr;
28. if (sock_.get_remote_addr(peerAddr) == 0 && peerAddr.addr_to_string(
29. peerName, MAXHOSTNAMELEN) == 0)
30. cout << "connection from " << peerName << endl;
31.
32. return this->reactor()->register_handler(this,
33. ACE_Event_Handler::READ_MASK);
34. }
35.
36. virtual ACE_HANDLE get_handle() const {
37. return sock_.get_handle();
38. }
39.
40. virtual int handle_input(ACE_HANDLE fd) {
41. const int INPUT_SIZE = 4096;
42. char buffer[INPUT_SIZE];
43.
44. ssize_t recv_cnt, send_cnt;
45. if ((recv_cnt = sock_.recv(buffer, sizeof(buffer))) <= 0) {
46. cout << "connection closed\n";
47. return -1;
48. }
49.
50. send_cnt = sock_.send(buffer, recv_cnt);
51. if (send_cnt == recv_cnt)
52. return 0;
53.
54. if (send_cnt == -1 && ACE_OS::last_error() != EWOULDBLOCK) {
55. cout << "send error\n";
56. return -1;
57. }
58.
59. return 0;
60. }
61.
62. virtual int handle_close(ACE_HANDLE handle, ACE_Reactor_Mask mask) {
63. if (mask == ACE_Event_Handler::WRITE_MASK)
64. return 0;
65. mask = ACE_Event_Handler::ALL_EVENTS_MASK
66. | ACE_Event_Handler::DONT_CALL;
67. reactor()->remove_handler(this, mask);
68. sock_.close();
69. delete this;
70. return 0;
71. }
72.
73. private:
74. ACE_SOCK_Stream sock_;
75.
76. };
77.
78. class EchoAcceptor: public ACE_Event_Handler {
79. public:
80. int open(const ACE_INET_Addr& listenAddr) {
81. if (acceptor_.open(listenAddr, 1) == -1) {
82. cerr << "acceptor.open error\n";
83. return -1;
84. }
85.
86. return reactor()->register_handler(this, ACE_Event_Handler::ACCEPT_MASK);
87. }
88.
89. virtual ACE_HANDLE get_handle() const {
90. return acceptor_.get_handle();
91. }
92.
93. virtual int handle_input(ACE_HANDLE fd = ACE_INVALID_HANDLE) {
94. EchoService* client = new EchoService;
95. auto_ptr<EchoService> p(client);
96.
97. if (acceptor_.accept(client->peer()) == -1) {
98. cerr << "Failed to accept client connection\n";
99. return -1;
100. }
101. p.release();
102.
103. client->reactor(this->reactor());
104. if (client->open() == -1)
105. client->handle_close(ACE_INVALID_HANDLE, 0);
106. return 0;
107. }
108.
109. virtual int handle_close(ACE_HANDLE handle, ACE_Reactor_Mask closeMask) {
110. if (acceptor_.get_handle() != ACE_INVALID_HANDLE) {
111. ACE_Reactor_Mask m = ACE_Event_Handler::ACCEPT_MASK
112. | ACE_Event_Handler::DONT_CALL;
113. reactor()->remove_handler(this, m);
114. acceptor_.close();
115. }
116.
117. return 0;
118. }
119.
120. virtual ~EchoAcceptor() {
121. handle_close(ACE_INVALID_HANDLE, 0);
122. }
123.
124. private:
125. ACE_SOCK_Acceptor acceptor_;
126. };
127.
128. int main() {
129. ACE_INET_Addr port_to_listen("8868");
130. EchoAcceptor acceptor;
131. acceptor.reactor(ACE_Reactor::instance());
132.
133. if (acceptor.open(port_to_listen) == -1)
134. return 1;
135.
136. ACE_Reactor::instance()->run_alertable_event_loop();
137.
138. return 0;
139. }
二、编译代码
$ g++-o"ace_echo_server" -g3 -Wall ace_echo_server.cpp -lACE
三、运行程序 ace_echo_server
$ ./ace_echo_server
四、用 telnet 命令作为客户端测试
新开启一个终端,注意:同样要登录到Linux实验室,执行: telnet localhost 8868
$ telnet localhost 8868
Trying ::1...
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
the firstline # 这是我们的输入
the firstline # 这是服务器async_tcp_echo_server 的回应,以下类推
the second line
the second line
welcome to xuanyuan-soft.org.cn!
welcome toxuanyuan-soft.org.cn!
这篇关于用ACE实现简易Echo Server的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!