ACE Socket wrapper façade提供的好处有

来源:互联网 发布:硬盘加密软件 编辑:程序博客网 时间:2024/06/06 01:07


ACE Socket wrapper façade提供的好处有:

①     提高了类型安全。对于该优点我的理解是:在不用ACE的情况下对SOCKET进行操作时,建立连接和收发两种功能都在同一个SOCKET下执行,那样我们很可能在没有建立连接的情况下就调用收发的方法,而此时的编译器并不能检测到这种错误。而用了ACE之后,我们将建立连接和收发两种功能分别封装在两个类中,我们无法在连接类中调用收发的行为,这样就避免了这种情况的发生。

②     保证可移植性。这个特点是不言而喻的,ACE的设计目的就是这样。

③     简化了常见的使用情况。这也是ACE设计的一个目的。

ACE中将C Socket API中的函数划分为三种角色:

①     主动连接者角色:对等应用程序中的一方扮演,用来发起一个对远程对等方的连接。

②     被动连接者角色:对等应用程序中的一方扮演,用来接收一个来自远程对等方的连接。

③     通信角色:由对等应用程序中的双方共同扮演,由于在建立连接后交换数据。

ACE中的地址类

ACE_Addr类位于ACE网络地址继承结构的根部。其中ACE_Addr类中定义了大量的方法。它还定义了一个静态的数据成员sap_any。ACE_INET_Addr继承自ACE_Addr类,他表示internet的地址连接。使用ACE_INET_Addr类的好处主要有两点:

①     它能够确保sockaddr_in中的所有字节都被初始化为零

②     它自动将端口号和IP地址转换为网络字节序。

ACE_IPC_SAP类

由于句柄会造成可移植方面的问题(比如在Linux和windows下的句柄概念就不同),所以ACE通过两种方式解决了这种不可移植问题:

①     提供了跨平台的ACE_HANDLE类型定义

②     定义了ACE_INVALID_HANDLE宏标志无效句柄(比如windows下为一个INVALID_HANDLE,UNIX为-1)。

解决移植问题还远远不够,我们还要实现面向对象,这样就出现了ACE_IPC_SAP类,该类提供了基本的I/O操作能力。当具体到网络编程方面时,产生了一个继承自ACE_IPC_SAP类的子类,ACE Socket wrapper façade的根类------ACE_SOCK。它也是一个抽象类,它为子类提供了创建/销毁socket句柄、获得对等端的网络地址和设置读取socket选项的方法。(ACE_SOCK类并没有在析构中关闭句柄,而是提供了一个close方法,我还不清楚)

ACE_SOCK_Connector类

Socket API在面向连接的协议中扮演了三种角色,但只有两种socket模式。

① 数据模式

② 被动模式

这样就没有一种socket模式来支持主动连接的角色。为了解决这个问题,特地定义了ACE_SOCK_Connnect类。由于Socket API不需要一个工厂socket来连接一个“数据模式”socket,所以ACE_SOCK_Connect类并不继承自ACE_SOCK。我对这点的理解是,在采用Socket API编程时,在客户端,也就是ACE_SOCK_Connector类发生作用的一端,并不需要一个socket句柄来标识,而服务器端必须有一个socket来标识。也就是说,客户端只需要一个面向连接的socket,而在服务器端则需要两个socket,一个面向连接,一个为服务器的socket。因此ACE_SOCK_Connector类不需要保留socket而ACE_SOCK_Acceptor需要保留一个socket。

ACE_SOCK_Stream类

ACE_SOCK_Stream类定义了一个数据模式下的只传输功能的对象。它继承自ACE_SOCK_IO类,在ACE_SOCK_Acceptor和ACE_SOCK_Connector工厂中初始化。

ACE_SOCK_Acceptor类

继承自ACE_SOCK类,又来被动的建立一个新的通信断点。

 

以下为我自己编写的联系代码

服务器端代码

int _tmain(int argc, _TCHAR* argv[])

{

     const char *pathname = "index.html";

     const char *server_hostname = "127.0.0.1";

 

     ACE_INET_Addr server_addr;

     ACE_SOCK_Acceptor acceptor;

     ACE_SOCK_Stream peer;

 

     if(server_addr.set(80)==-1)

         return 1;

     if(acceptor.open(server_addr)==-1)

         return 1;

     for (;;)

     {

         char buf[BUFSIZ];

         if(acceptor.accept(peer) == -1)

              return 1;

         std::cout<<"connect"<<std::endl;

 

         SSIZE_T n=peer.recv(buf,sizeof buf);

         ACE::write_n(ACE_STDOUT,buf,n);

 

         ACE::write_n(ACE_STDOUT,buf,n);

         if(peer.send_n(buf,n) == -1)

              return 1;

         peer.close();

     }

     return 0;

}

客户端代码

 

int _tmain(int argc, _TCHAR* argv[])

{

     const char *pathname = argc > 1?argv[1]:"index.html";

     const char *server_hostname = argc>2?argv[2]:"127.0.0.1";

     ACE_SOCK_Connector connector;

     ACE_SOCK_Stream peer;

     ACE_INET_Addr peer_addr;

 

     if(peer_addr.set(80,server_hostname)==-1)

     {

         std::cout<<"设置失败"<<std::endl;

         return 1;

     }

     else if(connector.connect(peer,peer_addr)==-1)

     {

         std::cout<<"连接失败"<<std::endl;

         system("pause");

         return 1;

     }

     char buf[BUFSIZ];

     iovec iov[3];

     iov[0].iov_base = "GET ";

     iov[0].iov_len = 4;

     iov[1].iov_base = (char*)pathname;

     iov[1].iov_len = strlen(pathname);

     iov[2].iov_base = "HTTP/1.0\r\n\r\n";

     iov[2].iov_len = 13;

     if(peer.sendv_n(iov,3) == -1)

         return 1;

     for(SSIZE_T n;(n=peer.recv(buf,sizeof buf))>0;)

     {

         ACE::write_n(ACE_STDOUT,buf,n);

     }

     system("pause");

     return 0;

}

 

0 0
原创粉丝点击