找回密码
 用户注册

QQ登录

只需一步,快速开始

楼主: psycheqiqi

proactor传文件的测试

[复制链接]
 楼主| 发表于 2009-10-26 16:26:00 | 显示全部楼层
[local]1[/local]
 楼主| 发表于 2009-10-26 16:29:26 | 显示全部楼层

回复 #40 wishel 的帖子

发短消息好像不能添加附件啊
发表于 2009-10-26 16:30:51 | 显示全部楼层
原帖由 psycheqiqi 于 2009-10-26 16:29 发表
发短消息好像不能添加附件啊

晕,是我的邮箱地址短消息给你了
这里发广告的多,邮箱地址尽量别公开
 楼主| 发表于 2009-10-26 16:37:35 | 显示全部楼层

回复 #43 wishel 的帖子

刚才没刷新,已经发过去了。
发表于 2009-10-26 16:50:39 | 显示全部楼层
汗。。好大,你把中间文件一起打了包了
我晚上有空帮你看下,你自己也再想想。
 楼主| 发表于 2009-10-26 17:01:47 | 显示全部楼层

回复 #45 wishel 的帖子

那个程序有很多问题:
1:一个客户端可以连接多次,相当于打开多个客户端连接。
2:服务器在发文件给客户端后,如果不接收的话再发消息就收不到。我测试的时候都是直接关掉客户端的进程然后重新连接。
3:在资源耗尽的情况下,我发送9.2M的文件给17个客户端就会出现发送失败的情况。
4:服务器端用的链表来记录连接的客户端的handle。
总之,代码很乱。
发表于 2009-10-27 16:19:34 | 显示全部楼层
程序是mfc带界面的,我没学过mfc。用的是vc9,编译不过,也不知道什么原因。错误信息:
sdkddkver.h(218) : fatal error C1189: #error :  _WIN32_WINNT settings conflicts with _WIN32_IE setting

粗看了下代码有很多不明白,client和server都有发送文件的代码?目前这么理解:多个client可以同时连server,且一个client可以有多个连接。server给每个连接都发送同一文件。
按照以上理解,简单的写个不带界面的程序。如果以上理解大体不差,稍作修改应该就可以用到你的程序里。

刚开始想跑下example的test_proactor.cpp的时候就杯具了:
写文件的时候过不去:
WIN32_Asynch_IO.cpp:
ACE_WIN32_Asynch_Write_File::write()->
ACE_WIN32_Asynch_Write_Stream::shared_write()->
::WSASend (reinterpret_cast<SOCKET> (result->handle ()),...)

出错信息:
handle is not a socket

我用的vs2008,ace为5.7.0。但是用minGW编译没有问题,正常写入文件。不知道什么原因,直接就是参数检查不过。不是明明写着reinterpret_cast<SOCKET>强制转了么,ms不知道搞什么。。。只好换minGW继续。

程序的思路比较简单,server接受client连接请求后,发文件给client,发完关闭连接。为进行流量控制,每个连接只分配一个message block。测试性能的话,可以尝试不同的MessageBlockSize设置。
发表于 2009-10-27 16:21:02 | 显示全部楼层

程序文件

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?用户注册

×
 楼主| 发表于 2009-10-28 10:55:31 | 显示全部楼层
原帖由 wishel 于 2009-10-27 16:19 发表
程序是mfc带界面的,我没学过mfc。用的是vc9,编译不过,也不知道什么原因。错误信息:
sdkddkver.h(218) : fatal error C1189: #error :  _WIN32_WINNT settings conflicts with _WIN32_IE setting

粗看了下代码有很多不明 ...

我在server端发送的时候
在private中定义了ACE_Message_Block *msgblock_;
在open中初始化  msgblock_= new ACE_Message_Block(8102);
在writeDate()中
  msgblock_->copy(szSendBuf,nSendCnt+1);
  int nResult= this->writer_.write(*msgblock_,nSendCnt+1);
在 handle_write_stream中
     result.message_block ().reset();
     if(fileflag)
     asynch_read_file();
在asynch_read_file()中只读一段文件。



我感觉确实可以,在测试时有一个现象
1:之前一直new messageblock的时候,我在服务器端发送文件,很快弹出发送完毕的对话框。
2:用一个messageblock的时候,同样在服务器端发送文件,客户端弹出的对话框在选择地址后才会接受文件,客户端接收完毕前服务器才会弹出发送完毕的对话框。
这是不是就说明了客户端在确认接收以后服务器才执行handle_write_stream,然后循环发余下的内容。

测试2:
1:用一个message block时可以发送300多M的文件,发送成功
2:若一直new messageblock, 发送9M*17个连接=150M文件都会发送失败。
说明跟解决发送的资源问题。(如果缓冲区在150M左右的话)

但是但是
但是还会出现在多连接时跳到发送失败 ACE_TRACE("Write data failed!");里面

到底为什么呢?

[ 本帖最后由 psycheqiqi 于 2009-10-28 11:52 编辑 ]
 楼主| 发表于 2009-10-28 10:57:27 | 显示全部楼层
virtual void handle_write_stream
  (const ACE_Asynch_Write_Stream::Result &result)
{
      result.message_block ().reset();
  if(fileflag)
           asynch_read_file();
  return;
}

void WriteDate(char *szSendBuf, int nSendCnt)
{
// ACE_Message_Block *smb = new ACE_Message_Block(nSendCnt+1);
// smb->copy(szSendBuf,nSendCnt+1);  

  msgblock_->copy(szSendBuf,nSendCnt+1);
  msgblock_->copy("");
  int nResult= this->writer_.write(*msgblock_,nSendCnt+1);
  if ( nResult != 0)
  {  
   CPserverDlg *dlg=(CPserverDlg*)AfxGetApp()->GetMainWnd();
   ACE_OS::sleep(0);
   ACE_TRACE("Write data failed!");
  }
    return ;  
}

void asynch_read_file()
{
CPserverDlg *dlg = (CPserverDlg*)AfxGetApp()->GetMainWnd();
int size=8100;
if(sendFileLen>size)
{
  char *membuf=new char[size+2];
  sendFile.Read(membuf,size);
  membuf[size] = '%';
  membuf[size+1] = '\0';
  
  sendFileLen = sendFileLen-size;
  
  list <HA_Proactive_Service *> ::iterator its;
  for(its=HA_Proactive_Service::List.begin();its!=HA_Proactive_Service::List.end();its++)
  {
   HA_Proactive_Service *curSvr = *its;
   curSvr->WriteDate(membuf,size+1);
  }
  delete []membuf;
  membuf = NULL;
  
}
else
{
  CHAR *membuf = new CHAR[sendFileLen+2];
  sendFile.Read(membuf,sendFileLen);
  sendFile.Close();
  membuf[sendFileLen] = '^';
  membuf[sendFileLen+1] = '\0';
  fileflag=false;
  list <HA_Proactive_Service *> ::iterator its;
  for(its=HA_Proactive_Service::List.begin();its!=HA_Proactive_Service::List.end();its++)
  {
   HA_Proactive_Service *curSvr = *its;
   curSvr->WriteDate(membuf,sendFileLen+1);  
  }
  delete []membuf;
  membuf = NULL;
     dlg->MessageBox((LPCTSTR)"文件已发送");
}
}

void CPserverDlg::OnFileSend()
{
// TODO: Add your control notification handler code here
    fileflag=true;
CString str;
sendFile.Abort();
    sendFile.Open(sendFileName,CFile::modeRead  | CFile::typeBinary);
sendFileLen = sendFile.GetLength();
CPserverDlg *dlg = (CPserverDlg*)AfxGetApp()->GetMainWnd();
str.Format("%d",sendFileLen);
dlg->MessageBox(str);  
  asynch_read_file();
}
您需要登录后才可以回帖 登录 | 用户注册

本版积分规则

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

GMT+8, 2024-11-22 18:39 , Processed in 0.016049 second(s), 4 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

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