ACE学习笔记--持续更新中

转载 2007年09月13日 23:54:00

1.动态获得端口号:
 ACE_Asynch_Acceptor<Receiver> acceptor;
  ACE_INET_Addr addr= ACE_INET_Addr("HAStatus");
  if (acceptor.open (addr,
                        initial_read_size,
                        1) == -1)
  return -1;

2.获得动态分配的端口号:
  ACE_SOCK_SEQPACK_Association a=ACE_SOCK_SEQPACK_Association(acceptor.get_handle());
  size_t addr_size=1;
  a.get_local_addrs(&addr,addr_size);
  ACE_DEBUG ((LM_DEBUG,"port:%d/n",addr.get_port_number()));

3.ACE在MFC中的使用
在程序运行之前调用       ACE::init();
在程序结束运行时调用  ACE::fini();
必须这样做,不然会出现通信不正常

4.ACE_InputCDRACE_OutputCDR字节错位的解决办法
         ACE_OutputCDR out(mb);

         out  << ?? ;     //这种方法简称out

         例一:

         如果out 了一个shortout一个long

         字节将成为如下排列(16进制)            xx xx ?? ?? xx xx xx xx

         其中,问号部分即是因为在long写入时进行的按long长度对齐。该数据是无意义的

         例二:

         如果out了一个charout一个 short

         字节将成为如下排列            xx  ??  xx xx

         其中,问号部分即是因为在short写入时进行的按short长度对齐。该数据是无意义的    

         例三:

         如果out了一个shortout一个char

         字节将成为如下排列            xx  xx    xx

         这里输入的char不会造成对齐问题,因为char只有一个字节(都是倍数)

         例四:

         如果out了一个shortout一个char out 一个 long

         字节将成为如下排列            xx  xx  xx  ??  xx  xx  xx  xx

         按照以上可总结出,每out一个类型的数据时,输出流将自动按照这个输入类型的长度序对齐,如果没有对齐,则自动填充。


         解决办法:
         A.全部用一种类型,比如全部用ACE_CDR::ULong
         B.打开ACE_ROOT/ace/config.h文件,加入以下一句
     #define ACE_LACKS_CDR_ALIGNMENT
    
重新编译ACE,将新的lib加入工程

5.ACE与MFC混用时的内存泄漏
         ACE 在MFC项目中存在内存泄露的问题主要是在ACE_Allocator内存分配器中,不过这个和ACE项目本身没什么问题,是MFC debug版本对new 和 delete操作做了一些处理,非MFC扩展DLL在MFC中都会出现这样的情况。如果你看这不舒服,我告诉你个最简单的方法解决这个问题。
第一、把项目中_AFXDLL编译开关去掉。
第二、把MDd改为MTd

6. 取得一个线程的执行时间效率

//定义开始时间
  LARGE_INTEGER fre,star_,end_;
  QueryPerformanceFrequency(&fre);
  QueryPerformanceCounter(&star_);

// 处理....
  pro( mb);


  //得到结束的时间
  QueryPerformanceCounter(&end_);
  ACE_DEBUG((LM_INFO,ACE_TEXT(" (%t) 处理时间%i/n"),
   long((end_.QuadPart - star_.QuadPart) * 10000 / fre.QuadPart)));

  这个地方打印出来的时间是1个单位为0.1个毫秒

7.解决网络数据粘包的问题
数据粘包,就是取得的数据可能有不完整的包,也可能完整的包和不完整的包混杂在一起, 这里介绍如何将完整的包从中分解出来

一个网络上来的数据包之后,我们必需将收到的数据包整理成为一个一个的完成的数据包.这里写了一个代码来搞定这个问题的.
首先我们需要有一个内存缓冲区.还有我们已经使用了这个缓冲区的大小的标志.


void getData(const char* buff,int nSize)
{
 char *pCheckBuff=(char*)buff; // 检查的缓冲区
 int nCountSize=nSize; // 缓冲区的大小
 bool bBuff=false; // 是否使用本地缓冲区

 // 如果以前有断的数据包
 if (nUsedSize_!=0)
 {
  memcpy(buf_+nUsedSize_,buff,nSize);
  nUsedSize_+=nSize;
  bBuff=true;
  nCountSize=nUsedSize_;
 }

 // 开始对 pCheckBuff 内存块进行解包
 // 当处理完成,或是数据包的长度没有这么长的时候退出
 int offset=0;
 int leave=nCountSize;
 while (1)
 {
  leave=nCountSize-offset;
  // 得到数据包头
  if (leave>DATA_HEAD_SIZE)
  {
   DataHead* pHead=(DataHead*)pCheckBuff+offset;
   // 检查数据包是否正确
   if (check_head(pHead))
   {
    // 检查数据体是否完整
    if (pHead->nSize<=leave)
    {
     ACE_Message_Block *new_mb = blockTash_.get_free_block();
     new_mb->copy(pCheckBuff+offset,pHead->nSize);
     //new_mb->wr_ptr(pHead->nSize);
     ((Acceptor*)pAcceptor_)->on_user_data(this->nIndex_,*new_mb,pHead->nSize);
     //
     // ((Acceptor*)pAcceptor_)->on_user_data(this->nIndex_,mb,result.bytes_transferred ());
     offset+=pHead->nSize;
    }
    // 不完整的数据包
    else
    {
     goto lable1;
    }
   }
   // 错误的数据包.将把这一次的数据全部丢失
   else
   {
    nUsedSize_=0;
    leave=0;
    break;
   }
  }
  // 没有完整的数据包头
  else
  {
   goto lable1;
  }
 }
 return ;

 // 保存数据
 // 移动缓冲区的数据
lable1:

 // 在本地的缓冲区中
 if (leave!=0)
 {
  memcpy(buf_,pCheckBuff+offset,leave);
  nUsedSize_=leave;
 }
 return ;
}

8.使用ACE_Task的时候要留意putq函数

在使用ACE_Task的时候,可以把这个对象看成一个处理器对象,他有一个消息队列,有一堆的线程在处理这一个消息。所以在应用中使用这个东西的机会特别的多。这次我使用的时候发现一个这样的问题。如果数据的速度太快了的时候将会使调用putq函数调用不成功。
这是一个例子代码,其实每一个Task都聚集了一个msg_queue对象的指针,他有一个参数:high_water_mark,就是说,在这个队列中的每个元素的size之和的最高。他的默认值是1024*16。但是有可能还是被占满了。如果发现putq不成功的时候就要使用这个东西来调整水位了。

int ACE_TMAIN(int, ACE_TCHAR *[])
{
 MyTask task;
 task.star();
 task.msg_queue_->high_water_mark(16385);
 ACE_Message_Block *new1=new ACE_Message_Block(16384);
 task.putq(new1);
 new1=new ACE_Message_Block(1);
 ACE_Time_Value tv(0,1000);

 if (task.putq(new1,&tv)==-1)
 {
  cout<<"put时失败"<<endl;
 }
 getchar();
 return 0;
}

         out << (ACE_CDR::UShort)1;

         out << (ACE_CDR::Long)2;

         ACE_LOG_MSG->log_hexdump( LM_DEBUG , mb->base() , out.length() , "t");

相关文章推荐

ACE学习笔记(一)

一、ACE_CDR::void mb_align (ACE_Message_Block *mb); { char * const start = ACE_ptr_align_binary (mb-...
  • dajjnan
  • dajjnan
  • 2012年05月11日 15:32
  • 613

ACE_TAO学习笔记

  • 2013年01月22日 11:14
  • 1005KB
  • 下载

ace tree和前台表格 的学习笔记

直接代码: bootstrop ace 框架 的树与前台表格(点击树的节点时显示出表格和分页) 实体类: package com.pcitc.hrsp.commons.model.mgnt...

ACE 2006 学习笔记

  • 2010年08月25日 13:05
  • 12.57MB
  • 下载

ACE网络编程学习笔记

  • 2012年04月18日 18:42
  • 1.91MB
  • 下载

ACE学习笔记一(基本的TCP/IP Socket用法)

1.基本的概念 连接器(Connector):主动建立连接ACE_SOCK_Connector 接收器(acceptor):被动建立连接ACE_SOCK_Acceptor 流(Stream):传...

ace tree和前台表格 的学习笔记

直接代码: bootstrop ace 框架 的树与前台表格(点击树的节点时显示出表格和分页) 实体类: package com.pcitc.hrsp.commons.model.mgnt...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:ACE学习笔记--持续更新中
举报原因:
原因补充:

(最多只允许输入30个字)