zoukankan      html  css  js  c++  java
  • ACE WINDOWS 配置

    1.编译,下载源码,直接解压到C盘

    2.在ace_wrapper下找到ace,里面有一个vc8.0版本的,直接编译 编译前要做1个事情:新建一个config.h,再往这个头文件添加如下内容: #define ACE_HAS_STANDARD_CPP_LIBRARY 1 #include "ace/config-win32.h"

    3.新建一个程序,记得设置程序的 配置属性---连接器--输入--附加依赖项,填写如下内容: C:\ACE_wrappers\lib\ACE.lib

    4.到这一步,你已经可以使用ace的lib了,但是为了进一步使用其功能,需要进行如下操作: 工具--选项--项目和解决方案---VC++目录--包含文件 输入: c:\ACE_wrappers 5.至此你已经可以成功编译ACE的例子了。

    over

    转一个例子:

    使用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地址转换成字符穿的形式来表示;

    CLIENT例子代码:
    #include "ace/Log_Msg.h"
    #include "ace/INET_Addr.h"
    #include "ace/SOCK_Stream.h"
    #include "ace/SOCK_Connector.h"
    #include "ace/SString.h"

    int ACE_TMAIN(int argc, ACE_TCHAR** argv)
    {
    ACE_INET_Addr svr(5000, ACE_LOCALHOST);
    ACE_SOCK_Stream peer;
    ACE_SOCK_Connector connector;
    ACE_TCHAR strBuffer[1024];
    ACE_SString strSend;
    ssize_t bytes_received = 0;

    if(connector.connect(peer, svr) == -1)
    {
      ACE_DEBUG( (LM_ERROR, ACE_TEXT("--> %p|%t connect failed\n"), ACE_TEXT("connect")) );
      return -1;
    }

    ACE_DEBUG( (LM_INFO, ACE_TEXT("connect server ok\n")) );

    strSend = "hello, ace server";
    peer.send_n(strSend.c_str(), strSend.length());

    ACE_OS::memset(strBuffer, 0, sizeof(strBuffer));
    bytes_received = peer.recv(strBuffer, sizeof(strBuffer));

    ACE_DEBUG( (LM_INFO, ACE_TEXT("receive from server: %s\n"), strBuffer) );

    peer.close();
    return 0;
    }

    SERVER例子代码:
    #include "ace/Log_Msg.h"
    #include "ace/INET_Addr.h"
    #include "ace/SOCK_Stream.h"
    #include "ace/SOCK_Acceptor.h"
    #include "ace/SString.h"

    int ACE_TMAIN(int argc, ACE_TCHAR** argv)
    {
    ACE_INET_Addr port_to_listen(5000, ACE_LOCALHOST), client_addr;
    ACE_SOCK_Acceptor acceptor;
    ACE_SOCK_Stream client;
    ACE_TCHAR strClientAddr[64], strBuffer[1024];
    ssize_t bytes_received = 0;

    if(acceptor.open(port_to_listen, 1) == -1)
    {
      ACE_DEBUG( (LM_ERROR, ACE_TEXT("--->%p\n"), ACE_TEXT("acceptor.open")) );
      return -100;
    }

    while(1)
    {
      if(acceptor.accept(client, &client_addr) == -1)
      {
       ACE_DEBUG( (LM_ERROR, ACE_TEXT("(%p | %t) failed to accept\n"), ACE_TEXT("client connection")) );
       acceptor.close();
       break;
      }

      client_addr.addr_to_string(strClientAddr, sizeof(strClientAddr));
      ACE_DEBUG( (LM_INFO, ACE_TEXT("client %s connected\n"), strClientAddr) );
      ACE_OS::memset(strBuffer, 0, sizeof(strBuffer));
      if(bytes_received = client.recv(strBuffer, sizeof(strBuffer)) == -1)
      {
       ACE_DEBUG( (LM_ERROR, ACE_TEXT("%p | %t received failed\n"), ACE_TEXT("cleint.recv")) );
       client.close();
       break;
      }

      ACE_DEBUG( (LM_INFO, ACE_TEXT("receive from client: [%d]%s\n"), bytes_received, strBuffer ) );

      client.send_n(strBuffer, ACE_OS::strlen(strBuffer));

      client.close();
    }

    acceptor.close();
    return 0;
    }

  • 相关阅读:
    JavaScript Patterns 5.7 Object Constants
    JavaScript Patterns 5.6 Static Members
    JavaScript Patterns 5.5 Sandbox Pattern
    JavaScript Patterns 5.4 Module Pattern
    JavaScript Patterns 5.3 Private Properties and Methods
    JavaScript Patterns 5.2 Declaring Dependencies
    JavaScript Patterns 5.1 Namespace Pattern
    JavaScript Patterns 4.10 Curry
    【Android】如何快速构建Android Demo
    【Android】如何实现ButterKnife
  • 原文地址:https://www.cnblogs.com/xianqingzh/p/1838235.html
Copyright © 2011-2022 走看看