帮忙分析下代码....
客户端发送文件的函数: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个字节? 我问你,二进制数据当字符串使用会有什么问题?
HA_Proactive_Service *curSvr = HA_Proactive_Service::GetObj();
curSvr->WriteDate(membuf,strlen(membuf));
回复 #2 winston 的帖子
是不是需要进行转化?我不大懂。请明示。回复 #2 winston 的帖子
我在之前写的用REACTOR机制来发送的程序,直接把从文件读出的二进制数据赋给字符串来发送是可以的,当时没用ace_message_block。很晕~是ace_message_block的原因吗?还是别的? 大哥们,在不在啊? strlen会对数据进行长度计算,C语言里面都是\0结尾,你的二进制数据这样计算,当然只发出一点了。
回复 #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 编辑 ]
回复 #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]