ACE Socket Wrapper Facade
-
ACE_Addr 类:
为ACE"网络地址"对象的统一接口,派生出ACE_INET_Addr来表示TCP/IP和UDP/IP的地址信息。
解决了将底层sockaddr_in中的所有字节初始化为0,将端口号和IP地址转换为网络字节顺序。 -
ACE_IPC_SAP类:
为其它ACE类提供了基本的“I/O句柄”操作能力,供子类(比如针对文件,STREAM管道的ACE wrapper facade)使用,而不供应用程序直接使用,所以构造函数为protected。 -
ACE_SOCK 类:
由上面ACE_IPC_SAP类派生出,可以创建和销毁socket句柄,获得本地和远程对等端的网络地址,设置和读取socket选项,如socket队列长度 -
ACE_SOCK_Connector类:
用于主动建立一个新的通信端,提供如下功能:
发起一个到对等接受者的连接,并在连接建立后初始化一个ACE_SOCK_Stream对象。
连接可以通过阻塞,非阻塞或定时方式发起。
运用C++ traaits,以支持泛型编程技术
其中由ACE_Time_Value值传给connect()方法来控制连接的方式,如NULL表示阻塞方式 -
ACE_SOCK_Stream类:
封装了“数据模式”socket支持的数据传输机制,只能用作“数据传输”角色。
派生自ACE_SOCK_IO,ACE_SOCK_IO派生自ACE_SOCK。
支持数据发送和接收
支持“分散读取”操作,这些操作涉及多个调用者提供的缓冲区,而不是单个连续的缓冲区
支持“集中写入”操作,在单个操作中传输多个非连续数据缓冲区中的数据
支持阻塞,非阻塞,定时等I/O操作
支持泛型编程 -
ACE_SOCK_Acceptor类:
是一个“工厂”,用来“被动”地建立一个新的通信端点
接受来自对等连接端的连接,并在连接建立后初始化ACE_SOCK_Stream对象
连接可以通过阻塞,非阻塞,定时方式接受
open()方法按顺序调用底层的socket(),bind()和listen()函数
该类的方法所调用的socket句柄,只会是那些已经被“被动模式”socket句柄工厂初始化了的socket句柄。
-ACE_Mem_Map类:
Win32和POSOX平台都提供了“内存映射”文件机制;该类封装了这一机制,这些调用使用了OS虚拟内存机制,将文件映射到一个进程的地址空间中。被映射的文件内容可以通过指针直接访问。较之通过读/写,系统I/O函数来访问数据块,其更方便,更高效,此外,“内存映射文件”可以被同一台机器上的多个进程共享。
#include "pch.h"
#include <iostream>
#include "ace/INET_Addr.h"
#include "ace/Sock_Connector.h"
#include "ace/SOCK_Stream.h"
#include "ace/Time_Value.h"
int main(int argc, char** argv)
{
const char *pathname = "index.html";
const char *server_hostname = "www.baidu.com";
ACE_SOCK_Connector connector;
ACE_SOCK_Stream peer;
ACE_INET_Addr peer_addr;
//同步connector,会阻塞直至连接成功或失败
if (peer_addr.set(80, server_hostname) == -1)
return 1;
else if (connector.connect(peer, peer_addr) == -1)
return 1;
//非阻塞,如果连接没有很快建立成功,它会反回-1,还会将errno设置为EWOULDBLOCK
//if (connector.connect(peer,
// peer_addr,
// &ACE_Time_Value::zero) == -1) {
// if (errno == EWOULDBLOCK) {
// 可以做一些其它事
// complete结束一个非阻塞连接并初始化一个ACE_SOCK_Stream
// if(connector.complete(peer,0,&ACE_Time_Value::zero) == -1)
// }
//}
//定时连接,如无法定时建立连接则返回-1并将errno设置为ETIME
//ACE_Time_Value timeout(10);
//if (connector.connect(peer, peer_addr, &timeout) == -1) {
// if(errno == ETIME)
// do something
//}
char buf[BUFSIZ];
iovec iov[3];
iov[0].iov_base = (char *)"GET ";
iov[0].iov_len = 4;
iov[1].iov_base = (char *)pathname;
iov[1].iov_len = strlen(pathname);
iov[2].iov_base = (char *)" 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);
return peer.close() == -1 ? 1 : 0;
}