ACE之旅——第一个ACE通讯程序daytime

ACE之旅——第一个ACE通讯程序

  ACE最大的用处就是通讯了,这个就不多说了,模仿Stevens的UNP第一个实例——daytime服务器、客户端。

  现从服务端svr.cpp开始,代码如下:

#include " ace/INET_Addr.h "
#include
" ace/SOCK_Stream.h "
#include
" ace/SOCK_Acceptor.h "
#include
" ace/Log_Msg.h "
#include
< time.h >

int ACE_TMAIN( int , ACE_TCHAR * []) {
ACE_INET_Addr port_to_listen(
" 50000 " );
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 );

while ( 1 ) {
   ACE_SOCK_Stream peer;
   ACE_INET_Addr peer_addr;
   ACE_Time_Value timeout(
10 , 0 );

   if (acceptor.accept(peer, & peer_addr, NULL, 1 ) == - 1 ) {
   if (ACE_OS::last_error() == EINTR)
   ACE_DEBUG((LM_DEBUG, ACE_TEXT(
" (%P|%t) Interrupted while " ),
   ACE_TEXT(
" waiting for connection\n " )));
   }
else {
   ACE_TCHAR peer_name[MAXHOSTNAMELEN];
   peer_addr.addr_to_string(peer_name, MAXHOSTNAMELEN);

   ACE_DEBUG((LM_DEBUG, ACE_TEXT(
" (%P|%t) Connectionfrom %s\n " ), peer_name));

   time_t ticks
= time(NULL);
   char timeBuf[ 128 ];

   memset(timeBuf,
0 , sizeof (timeBuf));
   ACE_OS::snprintf(timeBuf,
sizeof (timeBuf), " %.24s\r\n " , ctime( & ticks));

   peer.send_n(timeBuf, ACE_OS::strlen(timeBuf));
   peer.close();
   }
}
return 0 ;
}

  学过socket的人应该不会有太大的困难,用原生的BSD socket API编写TCP服务端一般需要socket、bind、listen、accept等几个函数,使用到得数据结构struct sockaddr_in等,在ACE下,分别如下对应

· ACE的ACE_SOCK_Acceptor::open完成了sock,bind,listen这几个动作。

· ACE的ACE_SOCK_Acceptor::accept对应accept函数功能。

· ACE_SOCK_Stream对应原生socket API中accept返回的对端fd。

· ACE_INET_Addr对应struct sockaddr_in等结构。

  只需知道这些类得基本功能、是做什么的,再通过几个小例子,结合官方doxygen生成的文档(http://www.dre.vanderbilt.edu/Doxygen/5.7.7/html/ace/index.html)查看某个类到底有哪些方法,ACE还是很好学的。

  客户端代码cli.cpp如下:

#include " ace/INET_Addr.h "
#include
" ace/SOCK_Stream.h "
#include
" ace/SOCK_Connector.h "
#include
" ace/Log_Msg.h "

int ACE_TMAIN( int , ACE_TCHAR * []) {
ACE_INET_Addr srvr(
50000 , ACE_LOCALHOST);
ACE_SOCK_Connector connector;
ACE_SOCK_Stream peer;

if (connector.connect(peer, srvr) == - 1 )
ACE_ERROR_RETURN((LM_ERROR, ACE_TEXT(
" %p\n " ), ACE_TEXT( " connect " )), 1 );

int bc;
char buf[ 64 ];

bc
= peer.recv(buf, sizeof (buf));
write(
1 , buf, bc);
peer.close();

return 0 ;
}

· ACE_SOCK_Connector::connect方法完成了原生socket API创建TCP客户端所需的socket、connect等函数的动作。

  编译这两个程序的makefile如下:

CC= g++
INCL = $(ACE_ROOT)/include
LIBS = $(ACE_ROOT)/lib

cli_deps = cli.cpp
svr_deps = svr.cpp

.SUFFIXES: .cpp.o
.cpp.o:
    $(CC) -g -I$(INCL) -c $*.cpp

all: cli svr

cli: $(cli_deps)
    $(CC) -g -I$(INCL) -L$(LIBS) -o cli $(cli_deps) -lACE
svr: $(svr_deps)
    $(CC) -g -I$(INCL) -L$(LIBS) -o svr $(svr_deps) -lACE

clean:
    -rm *~
    -rm cli
    -rm svr

  第一个使用ACE的socket通讯程序的实例,当然ACE远不止这些socket函数的封装之类的,接下来将使用ACE Reactor框架实现这个daytime程序。

(转载时请注明作者和出处。未经许可,请勿用于商业用途)
  更多文章请访问我的Blog: http://www.cnblogs.com/logicbaby


你可能感兴趣的:(time)