一 工具和下载

工具和环境:

Win7, VC++6, ACE5.4

可在Win7下运行的VC6下载:

http://blog.csdn.net/bcbobo21cn/article/details/44200205

ACE安装包和本文demo代码下载:

http://pan.baidu.com/s/1kUUOOlh

注意有两个ace安装包,5.4是dsw的工程,6.3是sln的工程

二 安装环境

下载ace54,解压;

在vc6.0中打开ace源码;

2个工程;网上资料有说3个工程;

在工程中双击config.h,询问是否要创建,单击是;

输入

#include "ace/config-win32.h"

看下lib目录,现在是空的;

在工程设置中作如下设置,

开始build;一堆cpp文件一个个被编译;

编译成功;

但是查看lib目录,空的;啥也没有;

生成了dll, 不在lib目录,并且没有生成lib文件;

重新修改工程设置如下图;

要改两处;

..\lib\aced.dll
/out:"..\lib\aced.dll" /implib:"..\lib\aced.lib"

这个和网上别的教程有所区别;大家可以参考之;

再bulid,好了,dll和lib都出来了;此框架就一个dll;

三 控制台demo

新建控制台工程;

新建一个空工程;

添加cpp源文件;

代码见后;

再新建客户端工程;前面那个是服务器端项目;

预处理器和附加包含路径;如下图;加入这个;

ACE_AS_STATIC_LIBS

添加lib库和附加库路径;

服务器端和客户端的代码;

#include "ace/Addr.cpp"  
#include "ace/Time_Value.cpp"  
#include "ace/Message_Queue.h"  
#include "ace/Asynch_IO.h"  
#include "ace/OS.h"  
#include "ace/Proactor.h"  
#include "ace/Asynch_Acceptor.h"  
#include "ace/SOCK_SEQPACK_Association.h"  
class Proactive_Service : public ACE_Service_Handler  
{  
public:  
    ~Proactive_Service ()  
    {  
        if (this->handle () != ACE_INVALID_HANDLE)  
            ACE_OS::closesocket (this->handle ());  
    }  
    /******************************************************/  
/*每当客户端连接到服务器就会调用此函数                 */  
    /******************************************************/  
    virtual void open (ACE_HANDLE h, ACE_Message_Block&)  
    {  
        this->handle (h);  
        //打开与客户端的读取流  
        if (this->reader_.open (*this) != 0 )  
        {  
            delete this;  
            return;  
        }  
        //开打与客户端的写出流  
        if (this->writer_.open (*this) != 0 )  
        {  
            delete this;  
            return;  
        }  
          
        ACE_Message_Block *mb = new ACE_Message_Block(buffer,1024);  
        if (this->reader_.read (*mb, mb->space ()) != 0)  
        {  
            ACE_OS::printf("Begin read fail/n");  
            delete this;  
            return;  
        }  
          
        return;  
    }  
      
    //异步读完成后会调用此函数  
    virtual void handle_read_stream  
        (const ACE_Asynch_Read_Stream::Result &result){  
        ACE_Message_Block &mb = result.message_block ();  
        //如果读取失败说明客户端关闭,在这里删除客户端连接资源  
        if (!result.success () || result.bytes_transferred () == 0)  
        {  
            mb.release ();  
            delete this;  
            return;  
        }  
          
        mb.copy("");    //为字符串添加结束标记'/0'  
        ACE_OS::printf("rev:/t%s/n",mb.rd_ptr());  
        mb.release();  
        ACE_Message_Block *mbb = new ACE_Message_Block(100);  
        mbb->copy("daye say hello");  
        if (this->writer_.write(*mbb,mbb->length()) !=0)  
        {  
            delete this;  
            return;  
        }  
        ACE_Message_Block *nmb = new ACE_Message_Block(buffer,1024);  
        if (this->reader_.read (*nmb, nmb->space ()) != 0)  
              
            return;  
    }  
  
    //异步写完成后会调用此函数  
    virtual void handle_write_dgram  
        (const ACE_Asynch_Write_Stream::Result &result)  
    {  
        ACE_Message_Block &mb = result.message_block ();  
        mb.release();  
        return;  
    }  
      
private:  
    ACE_Asynch_Read_Stream reader_;  
    ACE_Asynch_Write_Stream writer_;  
    char buffer[1024];  
};  
  
  
int main(int argc, char *argv[])   
{  
    ACE::init();//初始化dll资源  
    int port=20002;//指定监听端口  
    ACE_Asynch_Acceptor<Proactive_Service> acceptor;  
      
    //在指定的端口上进行监听  
    if (acceptor.open (ACE_INET_Addr (port)) == -1)  
        return -1;  
    //开始等待客户端的连接  
    ACE_Proactor::instance ()->proactor_run_event_loop();  
    ACE::fini();//释放dll资源  
    return 0;   
}

========

#include "ace/SOCK_Connector.h"  
#include "ace/OS_NS_string.h"  
#include "ace/OS_NS_stdio.h"  
#include "ace/Addr.cpp"  
#include "ace/Time_Value.cpp"  
#include "ace/Message_Queue.h"  
#include "ace/Asynch_IO.h"  
#include "ace/OS.h"  
#include "ace/Proactor.h"  
#include "ace/Asynch_Connector.h"  
  
class Proactive_Client : public ACE_Service_Handler  
{  
public:  
    ~Proactive_Client ()  
    {  
        if (this->handle () != ACE_INVALID_HANDLE)  
            ACE_OS::closesocket (this->handle ());  
    }  
      
    virtual void open (ACE_HANDLE h, ACE_Message_Block&)  
    {  
        this->handle (h);  
        if (this->reader_.open (*this) != 0 )  
        {  
            delete this;  
            return;  
        }  
        if (this->writer_.open (*this) != 0 )  
        {  
            delete this;  
            return;  
        }  
          
        ACE_Message_Block *mb = new ACE_Message_Block(buffer,1024);  
        if (this->reader_.read (*mb, mb->space ()) != 0)  
        {  
            delete this;  
            return;  
        }  
          
        ACE_OS::printf("connceted/n");  
        time_t now = ACE_OS::gettimeofday().sec();  
        char *time = ctime(&now);        //获取当前时间的字符串格式  
        ACE_Message_Block *mbb = new ACE_Message_Block(100);  
        mbb->copy(time);  
          
        if (this->writer_.write(*mbb,mbb->length()) !=0)  
        {  
            delete this;  
            return;  
        }  
      
        return;  
    }  
      
    //异步读完成后会调用此函数  
    virtual void handle_read_stream  
        (const ACE_Asynch_Read_Stream::Result &result)  
    {  
        ACE_Message_Block &mb = result.message_block ();  
        if (!result.success () || result.bytes_transferred () == 0)  
        {  
            mb.release ();  
            delete this;  
            return;  
        }  
          
        mb.copy("");    //为字符串添加结束标记'/0'  
        ACE_OS::printf("rev:/t%s/n",mb.rd_ptr());  
        mb.release();  
          
        ACE_Message_Block *nmb = new ACE_Message_Block(buffer,1024);  
        if (this->reader_.read (*nmb, nmb->space ()) != 0)  
              
            return;  
    }  
      
    //异步写完成后会调用此函数  
    virtual void handle_write_dgram  
        (const ACE_Asynch_Write_Stream::Result &result)  
    {  
        ACE_Message_Block &mb = result.message_block ();  
        mb.release();  
        return;  
    }  
      
private:  
    ACE_Asynch_Write_Stream writer_;  
    ACE_Asynch_Read_Stream reader_;  
    char buffer[1024];  
};  
  
int main(int argc, char *argv[])   
{  
    ACE::init();  
    ACE_INET_Addr addr(20002,"127.0.0.1");//服务器地址和端口  
    ACE_Asynch_Connector<Proactive_Client> connector;  
    connector.open();  
    if (connector.connect(addr) == -1)  
        return -1;  
    ACE_Proactor::instance()->proactor_run_event_loop();  
    ACE::fini();  
    return 0;   
}

运行下;

找不到dll,把前面生成的aced.dll直接拷贝到此工程生成的exe文件的同一目录下;再运行;看到客户端和服务器端通信了;不过此代码只能通信一次;一锤子而已;

要搞成项目需要自己搞定;

四 窗口模式的通信

新建一个MFC客户端;

做一个如下的界面;

在项目中加入四个文件;

========

RecvTask.h 
#ifndef RECVTASK_H  
#define RECVTASK_H  
  
#include "ace/Task.h"  
#include "ace/OS.h"  
#include "ace/INET_Addr.h"  
#include "ace/SOCK_Connector.h"  
#define MSG_LEN_BYTES 128  
#define TIME_OUT_VALUE 1000000    
  
class RecvTask: public ACE_Task<ACE_MT_SYNCH>  
{  
public:  
    RecvTask();  
    int open(void* p);  
    int close(u_long);  
    //接收服务器的信息  
    int svc(void);  
};  
#endif

RecvTask.cpp
#include "stdafx.h"  
#include "RecvTask.h"  
#include "ace/ACE.h"  
#include "ace/OS.h"  
#include "ace/SOCK_Connector.h"  
#include "ace/INET_Addr.h"  
#include "ace/Task.h"  
#include "Client.h"  
int RecvTask::svc(void)  
{  
    while(true)  
    {  
        Client::getInstance()->recvMessage();  
        ACE_OS::sleep(ACE_Time_Value( 0, 5000 ));  
    }  
}  
  
int RecvTask::open(void* p)  
{  
    activate();  
    return 0;  
}  
  
int RecvTask::close(u_long)  
{  
    return 0;  
}  
  
RecvTask::RecvTask(){}

Client.h
#ifndef CLIENR_H  
#define CLIENR_H  
#include "stdafx.h"  
#include "ace/ACE.h"  
#include "ace/OS.h"  
#include "ace/SOCK_Connector.h"  
#include "ace/INET_Addr.h"  
#include "ace/Task.h"  
#include "RecvTask.h"  
  
  
class Client  
{  
public:  
    ~Client();  
    /***************************************************************/  
    /* 根据ip地址和端口号,连接服务器,如果连接成功返回0,失败返回-1 */  
    /***************************************************************/  
  
    int connect(int port,char * localhost);  
  
    /***************************************************************/  
    /* 获取客户端实例                                              */  
    /***************************************************************/  
  
    static Client * getInstance();  
  
    /***************************************************************/  
    /* 给服务器发送数据信息,返回发的字节数                        */  
    /***************************************************************/  
    int sendMessage(char * msg);  
      
    /**************************************************************/  
    /* 关闭与远程服务器的连接,成功返回0,失败返回-1              */  
    /**************************************************************/  
    int close();  
      
    void recvMessage();  
  
private:  
    Client();  
    ACE_SOCK_Connector connector;  
    ACE_Thread_Mutex mutex;  
    RecvTask * recvTask;  
    static Client * instance;  
    static BOOL hasInstance;  
    ACE_SOCK_Stream stream;  
};  
#endif  
 
Client.cpp
#include "stdafx.h"  
#include "RecvTask.h"  
#include "ace/ACE.h"  
#include "ace/OS.h"  
#include "ace/SOCK_Connector.h"  
#include "ace/INET_Addr.h"  
#include "ace/Task.h"  
#include "Client.h"  
#include "ace/OS_NS_string.h"  
Client * Client::instance=NULL;  
BOOL Client::hasInstance=false;  
Client::~Client()  
{  
    if (recvTask!=NULL)  
    {  
        delete recvTask;  
        recvTask=NULL;  
    }  
  
}  
Client * Client::getInstance()  
{  
    if (!hasInstance)  
    {  
        instance= new Client();  
        hasInstance=true;  
    }  
    return instance;  
}  
int Client::connect(int port,char * localhost)  
{  
    recvTask = new RecvTask();  
    //stream = new ACE_SOCK_Stream();  
    ACE_INET_Addr  remote_addr(port,localhost);  
    int result=connector.connect(stream, remote_addr);  
    if (result==0)  
    {  
        recvTask->open(0);   
    }else{  
        recvTask->close(0);  
        delete recvTask;  
    }  
    return result;  
}  
int Client::sendMessage(char * msg)  
{  
    return stream.send_n(msg,ACE_OS::strlen(msg));  
    //return recvTask->getStream().send_n(msg,ACE_OS::strlen(msg));  
}  
void Client::recvMessage()  
{  
    size_t recv_len;  
    char sLen[MSG_LEN_BYTES + 1];  
      
    ACE_Time_Value t(0, TIME_OUT_VALUE / 2);  
    stream.recv_n(sLen, MSG_LEN_BYTES, &t, &recv_len);  
    if (recv_len!=0)  
    {  
        sLen[recv_len]=0;  
        AfxMessageBox(sLen);  
          
    }  
}  
int Client::close()  
{  
    recvTask->close(0);  
    stream.close();  
    return 0;  
}  
  
Client::Client()  
{  
  
}

========

为编辑框添加一个成员变量;

三个按钮代码;

连接

ACE::init();  
    if(Client::getInstance()->connect(20002,"127.0.0.1")==0)  
    {  
        AfxMessageBox("连接成功");  
    }else{  
        AfxMessageBox("连接失败");  
          
    }

添加到对话框实现文件头部
#include "ace/Addr.cpp"
#include "Client.h"

发送
UpdateData(true);
Client::getInstance()->sendMessage(m_send.GetBuffer(m_send.GetLength()));
 
“退出”按钮的代码
Client::getInstance()->close();  
ACE::fini();  
CDialog::OnCancel();

运行结果:

五 一个错误的解决-C2061、C2091、C2653、C2065

构建时出现下述错误,

Compiling...
WinClientDlg.cpp
c:\program files (x86)\microsoft visual studio\vc98\include\new(35) : error C2061: syntax error : identifier 'THIS_FILE'
c:\program files (x86)\microsoft visual studio\vc98\include\new(35) : error C2091: function returns function
......
Generating Code...
Compiling...
WinClient.cpp
Generating Code...
执行 cl.exe 时出错.

#include "ace/Addr.cpp"
#include "Client.h"

移动到对话框实现文件的最前面,再编译;

又出现,

Compiling...
WinClientDlg.cpp
C:\acedemo\demo1\WinClient\WinClientDlg.cpp(180) : error C2653: 'ACE' : is not a class or namespace name
C:\acedemo\demo1\WinClient\WinClientDlg.cpp(180) : error C2065: 'init' : undeclared identifier
......
C:\acedemo\demo1\WinClient\WinClientDlg.cpp(200) : error C2065: 'fini' : undeclared identifier
执行 cl.exe 时出错.

此时的头文件包含代码如下;

#include "ace/Addr.cpp"
#include "Client.h"

#include "stdafx.h"
#include "WinClient.h"
#include "WinClientDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

把文件包含代码改为如下;

#include "stdafx.h"
#include "WinClient.h"
#include "WinClientDlg.h"

#include "ace/Addr.cpp"
#include "Client.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

再构建;搞定;

以下是网上关于此错误的一段论述:

VC6提示 error C2061: syntax error : identifier 'THIS_FILE' 错误的解决办法

今天在编译一段以前写的代码时候,遇到了这样的错误
--------------------Configuration: AppSharePlugin - Win32 Debug--------------------
Compiling...
AppSharePluginModule.cpp
d:\program files\microsoft visual studio\vc98\include\new(35) : error C2061: syntax error : identifier 'THIS_FILE'
......
        d:\program files\microsoft visual studio\vc98\include\memory(16) : see declaration of 'new'
d:\program files\microsoft visual studio\vc98\include\memory(17) : error C2809: 'operator new' has no formal parameters
......
Error executing cl.exe.

AppSharePlugin.dll - 17 error(s), 0 warning(s)
 
双击第一个错误,居然跳转到了完全陌生的系统头文件
\microsoft visual studio\vc98\include\new(35)

中。开始怀疑是新老SDK混合引起的冲突,修改了几下参数,无果,只好向GOOGLE请教了。搜索一番之后很快明白了问题的所在,引起错误代码是这样的
 
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

//
//blah blah, lots of codes here
//

#include <vector>
using namespace std;
 
由于new已经被宏定义为DEBUG_NEW,所以在<vector>中包含的<new>中如下代码就出问题了:
void *__cdecl operator new(size_t) _THROW1(std::bad_alloc);

解决方法也很简单,把
#include <vector>
using namespace std;

两行代码,移到最前面即可!

六 安装和工程设置的文字描述

1.解压缩ace源代码包,假设在D:/ACE_wrappers
2.使用vc打开D:/ACE_wrappers/ace/ace.dsw
3.工作区上有三个工程,在ACE工程的头文件中找到config.h
4.双击打开这个文件,会有提示这个文件不存在是否创建,点是
5.在config.h中写入#include "ace/config-win32.h"表示windos 32位操作系统
6.在ACE工程上右键Settings... 选择c/c++ 在Caterory中选择 Code Generation 然后在 Use run-time library 中选择 Debug Multithreaded DLL
7.在ACE工程上右键 build(selection only)
8.编译后会在D:/ACE_wrappers/lib 目录中生成ACEd.lib ACEd.dll ACEd.exp ACEd.pdb等文件
9.D:/ACE_wrappers/ ACE-INSTALL.html有完整具体的安装指南

配置ace的工程
在使用到ace的工程中都要进行的一些设置
1.    选择Project->Settings...
2.    选择c/c++ 在Caterory中选择 Code Generation 然后在 Use run-time library 中选择 Debug Multithreaded DLL
3.    在Caterory中选择Preprocessor 在Preprocessor definitions 中添加ACE_AS_STATIC_LIBS 使用逗号与前面的内容隔开 在Additional include directories 中写入ACE的根目录D:/ACE_wrappers
4.    选择 Link 在Caterory中选择Input 在Additional library path 中加入D:/ACE_wrappers/lib 在Object/library modules 后追加aced.lib 用空格与前面的内容隔开
5.    设置完整以后重启vc

图解VC++6.0和ACE 5.4 开发入门相关推荐

  1. 计算机二级软件VC++6.0下载地址

    计算机二级软件VC++6.0介绍: 适合所有参加全国计算机等级考试的童鞋们--见图如下: 下载地址:(以下两者任选其一即可) (1).计算机二级软件VC++6.0(16.35MB) (2).计算机二级 ...

  2. 图解VC++2012编译安装GDAL1.11.0和入门例子

    相关下载 http://pan.baidu.com/s/1o7OEMc6 gdal1.rar - 入门例子 GDAL书籍代码及数据.rar gdal1110.zip - 下载的源码 GDAL.rar ...

  3. VC++ 6.0的小花招

    Visual Studio系列中产品中,Visual Studio 6.0是最经典的一个版本,虽然后来有Visual Studio .NET 2003,以及2005,也确实添加了很多让我觉得激动的特性 ...

  4. 使用VC++6.0创建MFC对话框程序

    使用VC++6.0创建MFC对话框程序

  5. vc 6.0的安装问题

    vc 6.0安装只需要 下载好压缩包 解压后,在E:\vc++6.0\Common\MSDev98\Bin目录下找到MSDEV然后随意改个名字叫MSDEV1然后点击它右键找到属性,找到兼容性选择 修改 ...

  6. vc 6.0常见编译错误及改正方法

    最常见VC++6.0编译错误信息集合 1.fatal error C1010: unexpected end of file while looking for precompiled header ...

  7. VC++ 6.0下OpengGL配置以及glut配置

    转自:http://blog.sina.com.cn/s/blog_5f0cf7bd0100c9oa.html OpenGL官方网站(英文) http://www.opengl.org 下面我将对Wi ...

  8. vc++ 6.0对话框上无法显示中文(乱码)

    是英文版的vc++,建立mfc向导时无法选择中文,到对话框里面改成中文还是乱码,怎么版啊 问题补充: 一般对话框是可以的,就是那个CPropertyPage 不可以对话框资源选成中文以后要ReBuil ...

  9. Basler相机Pylon4配置VC++6.0

    以前都是用到大恒相机,今天要配置两个Basler相机使用,记录一下过程 配置:VC++6.0,Basler相机 1,点击工程->设置 2,C/C++,Y分类选择Preprocessor 3,包含 ...

最新文章

  1. 从客户端(CourseIssueContent=P财务审计师岗位认证招生简章BR...)中检测到有潜在危险的 Request.Form 值。...
  2. 分布式系统:CAP 理论的前世今生
  3. ubuntu的mysql教程 pdf_Ubuntu上的MySQL字符集设置技巧
  4. Spring Boot学习总结(8)——SpringBoot Common application properties(application.properties)详解
  5. Zookeeper配置参数与节点值的解读
  6. k进制正整数的对k-1取余与按位取余
  7. 怎样访问远程服务器文件夹,远程访问服务器文件夹
  8. PWA 应用列表及常用工具
  9. 小暑海报文案|小暑海报设计图片素材
  10. netbeans java桌面应用程序_java – 使用Netbean的桌面应用程序的状态栏
  11. 【系】微信小程序云开发实战坚果商城-云开发之分类数据实现
  12. 滑膜间充质干细胞复合壳聚糖水凝胶/角蛋白壳聚糖水凝胶复合材料/壳聚糖/海藻酸纳复合水凝胶的制备
  13. 新面貌,新征程—读《新程序员》有感
  14. WBS(工作分解结构)
  15. Mikrotik ROS软路由配置PCC负载均衡实现双宽带叠加
  16. 哪些东西做引流产品比较好?哪些商品是每天比较受欢迎的?
  17. 网站导航怎么设置利于网站SEO优化
  18. Java实现 蓝桥杯 算法训练 Cowboys
  19. postgresql Count estimate
  20. LoRa + 蓝牙室内场馆定位技术全面解析

热门文章

  1. 正态分布||方差、均值的概念
  2. Sculpture ACM/ICPC NWERC 2008 离散化
  3. 7.1 matlab符号对象(符号对象的建立和四则运算)
  4. matlab 寻找二进制图像边缘
  5. mysql第一二章笔记_MYSQL必知必会读书笔记 第一章(基础)
  6. java mybatis拦截配置_SpringMvc拦截器配置_JavaEE框架(Maven+SpringMvc+Spring+MyBatis)全程实战教程_Java视频-51CTO学院...
  7. alpinestars与丹尼斯_骑行靴|丹尼斯VS A星心得分享,它和普通鞋子不同之处竟在这里!...
  8. XML和实体类之间相互转换(序列化和反序列化)
  9. BZOJ1406: [AHOI2007]密码箱 数论
  10. Median of Two Sorted Arrays