ACE入门学习之创建简单的服务器端和客户端
ACE自适配通行环境(Adaptive Communicatin Environment)是面向对象的框架和工具包。它为通信软件实现了核心的并发和分布式模式。
ACE具有分层的体系结构,基本分为三层:
1. 操作系统适配层(OS)
2. C++包装层
3. 框架和模式层
Shock类属(ACE_SOCK):
1. Dgram类和Stream类:Dgram类基于UDP数据报协议,提供不可靠的无连接消息传递功能。另一方面,Stream类基于TCP协议,提供面向连接的消息传递.
2. Acceptor、Connector类和Stream类:Acceptor和Connector类分别用于被动和主动地建立连接。Acceptor类封装BSD accept()调用,而Connector封装BSD connect()调用。Stream类用于在连接建立之后提供双向的数据流,并包含有发送和接收.
ACE中流包装中提供面向连接的通信,数据传输类包括ACE_SOCK_Stream类,建立连接的针对于TCP/IP的ACE_SOCK_Connector 和 ACE_SOCK_Acceptor.
创建一个服务器端所要创建的变量:
ACE_INET_Addr server_addr_;
ACE_SOCK_Acceptor
ACE_SOCK_Connector
ACE_SOCK_Stream
而客户端则多了个:
ACE_SOCK_Connector
服务器开启侦听代码:
//ACE_Server.h #include"ace/SOCK_Acceptor.h" #include"ace/SOCK_Stream.h" #include"ace/Log_Msg.h" #include"ace/Time_Value.h" #define SIZE_DATA 18 #define SIZE_BUF 1024 #define NO_INTERATION 5 class ACE_Server { public: ACE_Server(int port); ~ACE_Server(); int handle_connection(); int accept_connections(); private: char *data_buf_; ACE_INET_Addr server_addr_; ACE_INET_Addr client_addr_; ACE_SOCK_Acceptor peer_acceptor_; ACE_SOCK_Stream new_stream_; }; //ACE_Server.cpp #include"stdafx.h" #include"ACE_Server.h" ACE_Server::ACE_Server(int port) : server_addr_(port), peer_acceptor_(server_addr_) { data_buf_ = newchar[SIZE_BUF]; } ACE_Server::~ACE_Server() { delete []data_buf_; data_buf_ = NULL; } int ACE_Server::handle_connection() { for (int i=0; i < NO_INTERATION; i++) { int byte_count = 0; if ((byte_count = new_stream_.recv(data_buf_,SIZE_DATA,0)) == -1) { ACE_ERROR ((LM_ERROR, "%p\n", "Error in recv")); } else { data_buf_[byte_count] = '\0'; ACE_DEBUG((LM_DEBUG,"Server received %s \n",data_buf_)); } } if (new_stream_.close() == -1) ACE_ERROR((LM_ERROR, "%p\n","Close Error")); return0; } int ACE_Server::accept_connections() { if (peer_acceptor_.get_local_addr(server_addr_) == -1) ACE_ERROR_RETURN((LM_ERROR,"%p \n","Error in get_local_addr"),1); ACE_DEBUG((LM_DEBUG,"Starting server at port: %d \n",server_addr_.get_port_number())); while(1) { ACE_Time_Value timeout(ACE_DEFAULT_TIMEOUT); if (peer_acceptor_.accept(new_stream_,&client_addr_,&timeout) == -1) { ACE_ERROR((LM_ERROR,"%p \n","Accept")); continue; } else { ACE_DEBUG((LM_DEBUG,"Connection established with remote %s : %d \n", client_addr_.get_host_name(), client_addr_.get_port_number())); handle_connection(); } } } //main #include"ACE_Server.h" int _tmain(int argc, _TCHAR* argv[]) { WORD wVersionRequested; WSADATA wsaData; int err; wVersionRequested = MAKEWORD( 2, 2 ); err = WSAStartup( wVersionRequested, &wsaData ); if ( err != 0 ) { return0; } if ( LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 2 ) { WSACleanup( ); return0; } ACE_Server server(1234); server.accept_connections(); getchar(); return0; }
客户端
//Client.h: #define SIZE_BUF 128 #define NO_INTERATION 5 class ACE_Client_ { public: ACE_Client_(char* hostname, int port); int connect_to_server(); int send_to_server(); int close(); private: ACE_SOCK_Stream client_stream_; ACE_INET_Addr remote_addr_; ACE_SOCK_Connector connector_; char* data_buf_; }; //Client.cpp #include"stdafx.h" #include"Client.h" ACE_Client_::ACE_Client_(char* hostname, int port) : remote_addr_(port, hostname) { data_buf_ = "Hello from Client"; } int ACE_Client_::connect_to_server() { ACE_DEBUG((LM_DEBUG, "(%P | %T) Starting connect to %s:%d \n", remote_addr_.get_host_name(), remote_addr_.get_port_number())); if (connector_.connect(client_stream_, remote_addr_) == -1) { ACE_ERROR_RETURN((LM_ERROR,"(%p | %t) %p\n", "Connection failed"), -1); } else { ACE_DEBUG((LM_DEBUG, "(%P | %T) connected to %s\n", remote_addr_.get_host_name())); } return0; } int ACE_Client_::send_to_server() { for (int i=0; i < NO_INTERATION; i++) { if (client_stream_.send_n(data_buf_, strlen(data_buf_)+1, 0) == -1 ) ACE_ERROR_RETURN((LM_ERROR, "(%p | %t) %p\n", "send to"), 0); else ACE_DEBUG((LM_DEBUG, "(%T) Send Message to Server\n")); } close(); } int ACE_Client_::close() { if (client_stream_.close() == -1) ACE_ERROR_RETURN((LM_ERROR, "(%p | %t) %p \n", "close"), -1); else return0; } //main int _tmain(int argc, _TCHAR* argv[]) { WORD wVersionRequested; WSADATA wsaData; int err; wVersionRequested = MAKEWORD( 2, 2 ); err = WSAStartup( wVersionRequested, &wsaData ); if ( err != 0 ) { return0; } if ( LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 2 ) { WSACleanup( ); return0; } ACE_Client_ client("wangj",1234); client.connect_to_server(); client.send_to_server(); getchar(); return0; }