关闭

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

940人阅读 评论(0) 收藏 举报

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");

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:299741次
    • 积分:4670
    • 等级:
    • 排名:第6587名
    • 原创:95篇
    • 转载:113篇
    • 译文:0篇
    • 评论:84条
    最新评论