psycheqiqi 发表于 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 ;
sendFile.Read(membuf,size);
membuf = '%';
membuf = '\0';
HA_Proactive_Service *curSvr = HA_Proactive_Service::GetObj();
curSvr->WriteDate(membuf,strlen(membuf));
sendFileLen = sendFileLen-size;
LocalFree(membuf);
}
    char *membuf = new char;
sendFile.Read(membuf,sendFileLen);
sendFile.Close();
membuf = '^';
membuf = '\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 == '@')
{//文字信息
   buffer = '\0';
   CString str;
   str.Format("rev:\t%s\n",buffer);
   m_lbx->AddString(str);
   mb.release();
}
else
{
   if(buffer == '$')
   {//文件名
    buffer = '\0';
    recvFileName = buffer;
    dlg->MessageBox(recvFileName);
    }
   else
   {
    if(flag)
    {
   if (dlg->MessageBox("是否接收数据?","提示",MB_YESNO)==IDYES)
   {
      CString returnPath;
      TCHAR szPath;
      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 =='^')
       flag=true;
      return;
   }
    }
    if(buffer == '%')
    {
   buffer = '\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 =='^')
    {
   flag=true;
   buffer = '\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个字节?

winston 发表于 2009-10-14 10:01:17

我问你,二进制数据当字符串使用会有什么问题?
HA_Proactive_Service *curSvr = HA_Proactive_Service::GetObj();
curSvr->WriteDate(membuf,strlen(membuf));

psycheqiqi 发表于 2009-10-14 10:05:33

回复 #2 winston 的帖子

是不是需要进行转化?我不大懂。请明示。

psycheqiqi 发表于 2009-10-14 10:20:02

回复 #2 winston 的帖子

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

很晕~是ace_message_block的原因吗?还是别的?

psycheqiqi 发表于 2009-10-14 10:40:57

大哥们,在不在啊?

winston 发表于 2009-10-14 11:21:24

strlen会对数据进行长度计算,C语言里面都是\0结尾,你的二进制数据这样计算,当然只发出一点了。

psycheqiqi 发表于 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 编辑 ]

psycheqiqi 发表于 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的处理问题?


我现在好晕
页: [1]
查看完整版本: 帮忙分析下代码....