该类属中的类都位于ACE_SOCK之下;它提供使用BSD socket编程接口的Internet域和UNIX域协议族的接口。这个类属中的类被进一步划分为: Dgram类, Acceptor类和Stream类:Dgram类基于UDP数据报协议,提供不可靠的无连接消息传递功能。另一方面,Stream类基于TCP协议,提供面向连接的消息传递。 、Connector类和Stream类:Acceptor和Connector类分别用于被动和主动地建立连接。Acceptor类封装BSD accept()调用,而Connector封装BSD connect()调用。Stream类用于在连接建立之后提供双向的数据流,并包含有发送和接收方法。

类名

职责

ACE_SOCK_Acceptor

用于被动的连接建立,基于

BSD accept()和listen()调用。

ACE_SOCK_Connector

用于主动的连接建立,基于

BSD connect()调用。

ACE_SOCK_Dgram

用于提供基于

UDP(用户数据报协议)的无连接消息传递服务。封装了sendto()和receivefrom()等调用,并提供了简单的send()和recv()接口。

ACE_SOCK_IO

用于提供面向连接的消息传递服务。封装了

send()、recv()和write()等调用。该类是ACE_SOCK_Stream和ACE_SOCK_CODgram类的基类。

ACE_SOCK_Stream

用于提供基于

TCP(传输控制协议)的面向连接的消息传递服务。派生自ACE_SOCK_IO,并提供了更多的包装方法。

ACE_SOCK_CODgram

用于提供有连接数据报(

connected datagram)抽象。派生自ACE_SOCK_IO;它包含的open()方法使用bind()来绑定到指定的本地地址,并使用UDP连接到远地地址。

ACE_SOCK_Dgram_Mcast

用于提供基于数据报的多点传送

(multicast)抽象。包括预订多点传送组,以及发送和接收消息的方法

ACE_SOCK_Dgram_Bcast

用于提供基于数据报的广播

(broadcast)抽象。包括在子网中向所有接口广播数据报消息的方法

ACE的Socket

 

使用ACE进行Socket编程,需要使用到下面几个类:
    ACE_SOCK_Connector:连接器,主动建立连接,用于Socket Client;
    ACE_SOCK_Acceptor:接受器,被动建立连接,用于Socket Server;
    ACE_SOCK_Stream:传输数据的流,用于传输数据;
    ACE_INET_Addr:用于表示通信端点的地址;
    ace/INET_Addr.h文件中定义了一些有用的ACE_INET_Addr构造函数,用于创建通信端点的地址;一旦构造好一个通信端点的ACE_INET_Addr信息,那么,就可以使用这个地址去连接服务器了;ACE中使用ACE_SOCK_Stream类的对象来表示已经连接成功的TCP Socket;之所以这样命名,是因为TCP连接代表的是面向连接的虚连接,或者是"字节流";
    短写问题:当你试图把一些字节写往远程主机时,由于网络缓冲区溢出、拥塞,或其它任何原因,导致你的字节没有被全部送出去,那么随后,你必须移动你的数据指针,发送剩余的数据;你必须持续地做这样的发送操作,直到把原来所有的自己全部都发送出去为;止.这样的问题在网络编程中发生的非常频繁,ACE的send_n()方法调用封装了这些操作,它会把所有这些重试操作都变成了它自己内部的事务,这样,只有把指定的字节全部都发送完,或者时发送时遇到错误,它才返回;
    短读问题:当你试图从远程主机接收一些数据的时候,由于网络的拥塞、延迟等原因,会导致你不能一次性地接收到全部的数据;这个时候,你就必须通过计算已经接收到的数据的字节数,来接收剩余的数据;recv()方法,它将从对端读取最多n个字节的数据,并把这n个自己的数据放到自己的接收缓冲区中;当然,如果你确切地知道需要接收的数据的字节数,那么就必须处理"短读"问题;ACE提供了recv_n()方法调用为你解决了"短读"问题,它与send_n()方法一样,你必须告诉它需要读取的确切的字节数,它会在调用返回之前接收到你所指定的全部字节数的数据;
    ACE_INET_Addr::set():这个方法比较灵活,使用它,可以修改地址对象的各个属性,这样可以重复使用一个地址对象,而不用创建多个地址对象;与ACE_INET_Addr的构造函数一样灵活;当set()调用失败的时候,set()方法返回-1,可以使用ACE_OS::last_error()检查错误码;Unix或类Unix中,ACE_OS::last_error()只是简单地返回errno的值,但是一在Windows中,它会调用GetLastError()函数来返回错误码;
    ACE_SOCK_Connector::connet():主动连接服务器;连接失败,返回-1;连接成功,返回0;大多数情况下,你会让操作系统为你选择本地端口,ACE使用ACE_Addr::sap_any来表示这个值;但是在很多情况下,你可能想自己选择本地端口值;也就时说,我们在作为客户而主动连接服务器的时候,可以选择客户使用的本地端口;这是不很安全的保护应用的一种做法,但是可以在防止欺骗方面发挥作用;我们可以在我们的连接上设置服务质量参数,甚至是启动阻塞与非阻塞连接操作;对于Socket上面的操作,它们都支持为长时间运行的操作设置超时时间;与ACE_SOCK_Connector的connect方法一样,我们需要根据我们所需要的超时时间提供一个ACE_Time_Value类的对象;比如:send_n()、recv_n()等操作都可以接收一个ACE_Time_Value对象作为超时时间参数;
    readv()、writev()分别与read()和write()的区别:
    readv()和writev()与read()和write()的功能一样,都是系统调用,都是IO的读写系统调用,但是read()和write()必须用于连续的数据区域,而readv()和writev()则是可以用于不连续的数据区域或数据块;可以使用结构体iovec的数组来定义不连续的数据区;readv()和writev()以及结构iovec都是在BSD4.3操作系统中引入的,最常用于需要使用非连续的缓冲区来接收和发送数据的情况下;常见的例子就是,发送一个包头和一个与这个包头相关联的、存放在另外一个缓冲区中的数据;如果使用标准的系统调用write()的话,你必须连续两次调用write()来分别发送头和体,这样的操作比较麻烦,而且效率也跟不上;如果你能把头和体合在一起能按照一种原子方式写出去,或者是需要避开Nagle算法, 进行两次调用是不可接受的;如果你把头和体都复制到一个更大的缓冲区中,那么这在内存需求上不太现实;那么这个时候可以选择使用系统调用writev()和结构体iovec的数组来解决这个问题;writev()和ACE_SOCK_Stream::sendv()这两个方法会按照原子的方式把结构体iovec的数组中的所有条目都一一地发送出去;而readv()和ACE_SOCK_Stream::recvv()则与writev()和ACE_SOCK_Stream::sendv()相反,它们两个则是把接收到的数据依次填充到结构体iovec的数组中的每个条目所标记的不连续的缓冲区中,然后写指针移向下一个不连续的缓冲区的起始位置处;
typedef char*  caddr_t;       /* ?<core address> type */
struct iovec
{
  int     iov_len;
  caddr_t iov_base;
};
    成员iov_base可以指向内存映射文件区域、共享内存段或者是其它某个有意义的地方;你可以自己指定接收缓冲区地址,也可以让recvv()方法自动为你分配接收缓冲区,并用指针和缓冲区的长度来填充iovec结构,recvv()方法会计算到底有多少数据要接收,并分配一个大小刚好与要接收的数据的大小相同的缓冲区;如果你不清楚对方到底有多少数据要发送给你,但你相当地清楚,这些数据全都能放进一个尺寸合理的空间中,而且你希望这块空间是连续的,那么这个功能就可以使用上了;但是,一定要注意,由于是recvv()方法帮你分配的接收缓冲区,所以,在你使用完这些缓冲区之后,一定要记着释放这些内存空间,以避免内存泄露;
    ACE_const_cast(type, variable);
    ACE_static_cast(type, variable);
    ACE_reinterpret_cast(type, variable);
    这三个函数都是执行变量类型转换的,它们把变量variable的类型转换成type类型;
    构建一个服务器:
    要创建一个服务器,首先需要创建一个ACE_INET_Addr类的对象,以定义你想要用于侦听连接请求的端口.随后,需要使用一个ACE_SOCK_Acceptor对象在该端口上打开一个侦听器;ACE_SOCK_Acceptor::accept()方法会照管低层的细节,包括bind()、listen()、accept()等动作;如果accept()方法调用成功,那么会通过accept()的参数返回一个已经初始化成功的有效对端对象,它代表与客户端通讯的连接;
    值得一提的是:在默认情况下,如果accept()方法被某一个UNIX信号中断了,那么它将会重启自身.对你的应用而言,这可能是合适的,也可能是不合适的;我们可以通过accept()方法的第四个参数来指定是否需要重启accept()方法自身,如果该参数的值为0,那么就表示,当accept()方法被信号中断之后,accept()方法不需要重启自身,而是返回-1,表示出错;如果该参数的值是1,则表示accept()方法被信号中断之后,accept()方法需要重启自身;
    如果accept()方法调用成功,并返回了一个客户连接,那么在同时,它也会把已经连接上来的客户端的地址信息填充到一个ACE_INET_Addr对象中;ACE_INET_Addr::addr_to_string(),这个方法用于把IP地址转换成字符穿的形式来表示;

ACE_SOCK的更多相关文章

  1. ACE Socket Wrapper Facade

    ACE Socket Wrapper Facade 1:Socket API 1.1 IPC(进程间通信) IPC分为本地IPC(同一计算机上的不同进程)和远程IPC(网络互联的不同计算机),本地IP ...

  2. ACE网络编程:IPC SAP、ACE_SOCKET和TCP/IP通信实例

    socket.TLI.STREAM管道和FIFO为访问局部和全局IPC机制提供广泛的接口.但是,有许多问题与这些不统一的接口有关联.比如类型安全的缺乏和多维度的复杂性会导致成问题的和易错的编程.ACE ...

随机推荐

  1. initWithFrame方法的理解

    initWithFrame方法的理解   有时候,知道initWithFrame方法如何用,但是么有弄明白initWithFrame方法到底是什么? 那就通过查资料弄明白.     1. initWi ...

  2. Junit单元测试学习笔记一

    我们在编写大型程序的时候,需要写成千上万个方法或函数,这些函数的功能可能很强大,但我们在程序中只用到该函数的一小部分功能,并且经过调试可以确定,这一小部分功能是正确的.但是,我们同时应该确保每一个函数 ...

  3. POJ3176——Cow Bowling(动态规划)

    Cow Bowling DescriptionThe cows don't use actual bowling balls when they go bowling. They each take ...

  4. ADB调试桥安装(方式一)

    一.ADB简介 adb的全称为Android Debug Bridge,起到调试桥的作用.它android sdk里的一个工具, 用这个工具可以直接操作管理 android模拟器或者真实的androi ...

  5. ubuntu启动eclipse时出错cannot open display

    由于要学习hadoop,就在ubuntu下创建了一个hadoop用户,但是eclipse是在naomi用户下装的,在root和naomi用户下都能正常启动,但是一旦切换到hadoop用户,试着启动ec ...

  6. 在 MapPath 的 Path 参数中不允许出现“..”字符。

    找到IIS应用程序池,“设置应用程序池默认属性”->“常规”->”启用 32 位应用程序”,设置为 True. 这样我的问题就解决了..

  7. spry菜单栏(一)

    spry菜单栏使用教程 关于 Spry 框架 Spry 框架是一个 JavaScript 库,Web 设计人员使用它可以构建能够向站点访问者提供更丰富体验的 Web 页.有了 Spry,就可以使用 H ...

  8. Linux 下sleep()函数

    调试程序发现起了一个子线程后,主线程上的sleep不生效了,看到这才明白... — Function: unsigned int sleep (unsigned int seconds) The sl ...

  9. ubuntu安装和配置SVN【转】

    ubuntu安装和配置SVN 转自:http://www.jb51.net/os/Ubuntu/56394.html 第一步:安装apache2  libapache2-svn subversion ...

  10. Java动手实验及课后程序

    课后作业 一.编写程序,消息框显示计算结果 设计思想:导入Scanner包,使用JOptionPane类来实现消息框的输入和结果的显示. 程序代码: package com; import java. ...