找回密码
 用户注册

QQ登录

只需一步,快速开始

查看: 3797|回复: 7

帮忙分析下代码....

[复制链接]
发表于 2009-10-14 09:46:27 | 显示全部楼层 |阅读模式
客户端发送文件的函数:
void CPclientDlg::OnFileSend()
{
// TODO: Add your control notification handler code here
CString str;
sendFile.Abort();
    sendFile.Open(sendFileName,CFile::modeRead  | CFile::typeBinary);
sendFileLen = sendFile.GetLength();
CPclientDlg *dlg = (CPclientDlg*)AfxGetApp()->GetMainWnd();
str.Format("%d",sendFileLen);
dlg->MessageBox(str);

int size=8100;
while(sendFileLen>size)
{
  char *membuf=new char[size+2] ;
  sendFile.Read(membuf,size);
  membuf[size] = '%';
  membuf[size+1] = '\0';
  HA_Proactive_Service *curSvr = HA_Proactive_Service::GetObj();
  curSvr->WriteDate(membuf,strlen(membuf));
  sendFileLen = sendFileLen-size;
  LocalFree(membuf);
}
    char *membuf = new char[sendFileLen+2];
sendFile.Read(membuf,sendFileLen);
sendFile.Close();
membuf[sendFileLen] = '^';
membuf[sendFileLen+1] = '\0';
HA_Proactive_Service *curSvr = HA_Proactive_Service::GetObj();
    curSvr->WriteDate(membuf,strlen(membuf));
LocalFree(membuf);
MessageBox("文件已发送");
}

int WriteDate(char *szSendBuf, int nSendCnt)
{
  ACE_Message_Block *smb = new ACE_Message_Block(nSendCnt+1);
  smb->copy(szSendBuf);
  CPclientDlg *dlg = (CPclientDlg*)AfxGetApp()->GetMainWnd();
  CString str;
  str.Format("%d",smb->length());
  dlg->MessageBox(str);
  int nResult = this->writer_.write(*smb,smb->length());
  if ( nResult != 0)
  {
   ACE_TRACE("Write data failed!");
  }
  
  return nResult;
}

服务器在open函数中初始了
ACE_Message_Block *mb;
  ACE_NEW_NORETURN(mb,ACE_Message_Block(8102));
  
服务器接受文件的函数:
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;
  }
  
  CPserverDlg *dlg=(CPserverDlg*)AfxGetApp()->GetMainWnd();
  
//  mb.copy("\0");    //为字符串添加结束标记'\0'
  char *buffer = mb.rd_ptr();
  int length= mb.length()-1;
  CString str1;
  str1.Format("%d",length);
  dlg->MessageBox(str1);
  if(buffer[length-1] == [email=]'@'[/email])
  {//文字信息
   buffer[length-1] = '\0';
   CString str;
   str.Format("rev:\t%s\n",buffer);
   m_lbx->AddString(str);
   mb.release();
  }
  else
  {
   if(buffer[length-1] == '$')
   {//文件名
    buffer[length-1] = '\0';
    recvFileName = buffer;
    dlg->MessageBox(recvFileName);
    }
   else
   {
    if(flag)
    {
     if (dlg->MessageBox("是否接收数据?","提示",MB_YESNO)==IDYES)
     {
      CString returnPath;
      TCHAR szPath[MAX_PATH];
      BROWSEINFO bInfo;
      bInfo.hwndOwner = NULL;
      bInfo.pidlRoot  = NULL;
      bInfo.pszDisplayName = szPath;
      bInfo.lpszTitle ="请选择目的路径";
      bInfo.ulFlags = BIF_BROWSEINCLUDEFILES|BIF_RETURNFSANCESTORS|BIF_RETURNONLYFSDIRS|BIF_BROWSEFORCOMPUTER;
      bInfo.lParam  =NULL;
      bInfo.lpfn  =NULL;
      
      LPITEMIDLIST lpList =  SHBrowseForFolder(&bInfo);
      SHGetPathFromIDList(lpList,szPath);
      
      filePath = szPath ;
      filePath += "\\";
      //用来区分哪个客户端发来的文件,把其IP地址放在文件名的前一级目录。
      //   filePath += peer_name
      //    filePath += "\\";
      filePath += recvFileName;
      dlg->MessageBox(filePath);
      //往文件里写内容
      //保存文件对话框的问题
      flag=false;
     }
     else
     {
      if( buffer[length-1] =='^')
       flag=true;
      return;
     }
    }
    if(buffer[length-1] == '%')
    {
     buffer[length-1] = '\0';
     if (file_connector.connect(file,
      ACE_FILE_Addr (filePath),
      0,
      ACE_Addr::sap_any,
      0,
      O_RDWR|O_CREAT|O_APPEND |O_BINARY
      ) == -1)
     {
      printf("error");
     }
     
     int len=length-1;
   
     if (file.send (buffer, len) != len)
      printf("send error");
     //所传文件的信息     
     if (file.close () == -1)
      printf("close error");
     
    }  
   
    if(buffer[length-1] =='^')
    {
     flag=true;
     buffer[length-1] = '\0';
     if (file_connector.connect(file,
      ACE_FILE_Addr (filePath),
      0,
      ACE_Addr::sap_any,
      0,
      O_RDWR|O_CREAT|O_APPEND |O_BINARY
      ) == -1)
     {
      dlg->MessageBox((LPCTSTR)"open error");
     }
     
     int len=length-1;
     if (file.send (buffer, len) != len)
      dlg->MessageBox((LPCTSTR)"send error");
     //所传文件的信息     
     if (file.close () == -1)
      dlg->MessageBox((LPCTSTR)"close error");
     dlg->MessageBox("传送完毕");
    }   
     LocalFree(buffer);     
   }
  }  
  ACE_Message_Block *nmb;
  ACE_NEW_NORETURN(nmb,ACE_Message_Block(8102));
  if (this->reader_.read (*nmb, nmb->space ()) != 0)
           return;
}

问题:
1.现在可以发送任意大的文本文件。
发送过程,如果大于8100,先按8100个字节来截断,然后依次发送。成功
2。但我如果发送别的文件,比如压缩包。发送的时候最开始只发送5个字节(好像是),没有发送8100个字节?
发表于 2009-10-14 10:01:17 | 显示全部楼层
我问你,二进制数据当字符串使用会有什么问题?
HA_Proactive_Service *curSvr = HA_Proactive_Service::GetObj();
  curSvr->WriteDate(membuf,strlen(membuf));
 楼主| 发表于 2009-10-14 10:05:33 | 显示全部楼层

回复 #2 winston 的帖子

是不是需要进行转化?我不大懂。请明示。
 楼主| 发表于 2009-10-14 10:20:02 | 显示全部楼层

回复 #2 winston 的帖子

我在之前写的用REACTOR机制来发送的程序,直接把从文件读出的二进制数据赋给字符串来发送是可以的,当时没用ace_message_block。

很晕~是ace_message_block的原因吗?还是别的?
 楼主| 发表于 2009-10-14 10:40:57 | 显示全部楼层
大哥们,在不在啊?
发表于 2009-10-14 11:21:24 | 显示全部楼层
strlen会对数据进行长度计算,C语言里面都是\0结尾,你的二进制数据这样计算,当然只发出一点了。
 楼主| 发表于 2009-10-14 11:38:11 | 显示全部楼层

回复 #6 winston 的帖子

但我改了curSvr->WriteDate(membuf,size+1);size+1为应该发送的字节数。
writeData()里int nResult = this->writer_.write(*smb,nSendCnt+1);发送改成nSendCnt+1

ace_message_block 的长度mb.getlength()是怎么判断长度的?和strlen()一样吗?

[ 本帖最后由 psycheqiqi 于 2009-10-14 11:53 编辑 ]
 楼主| 发表于 2009-10-14 13:27:01 | 显示全部楼层

回复 #7 psycheqiqi 的帖子

我把writeDate函数修改如下       
        int WriteDate(char *szSendBuf, int nSendCnt)
        {
                ACE_Message_Block *smb = new ACE_Message_Block(nSendCnt+1);
                smb->copy(szSendBuf);      
                int nResult = this->writer_.write(*smb,nSendCnt+1);
                if ( nResult != 0)
                {
                        ACE_TRACE("Write data failed!");
                }
               
                return nResult;
        }
write(*smb,nSendCnt+1);应该确实发送了正确的字节数,否则不会成功

但在服务器的接收端
ACE_Message_Block &mb = result.message_block ();
if (!result.success () || result.bytes_transferred () == 0)       

在此测试的result中的值就只有很少?是不是ace_message_block的处理问题?


我现在好晕
您需要登录后才可以回帖 登录 | 用户注册

本版积分规则

Archiver|手机版|小黑屋|ACE Developer ( 京ICP备06055248号 )

GMT+8, 2024-12-23 13:17 , Processed in 0.024603 second(s), 5 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表