CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
山寨机中的战斗机! 程序优化工程师到底对IT界有没有贡献
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  VC/MFC >  网络编程

一个完成端口的问题,帮忙看一下问题出在那,谢谢

楼主zxs0001(盛)2004-07-03 12:23:18 在 VC/MFC / 网络编程 提问

 
  下面这个是完成端口的工作线程,收到客户端的数据后,又原封不动的发回客户端,可怎么也发不回去呀,收没问题!  
  1、大家帮忙看看,问题出在什么地方!怎么改才能成功投递一个WSASend()操作呀!  
  2、还有就是完成键的怎样定义才合适(既要发数据,又要收数据),GetQueuedCompletionStatus()返回后是怎么修改这个完成键的!  
   
  //工作线程用到的数据结构  
  #define   RECV_POSTED       1  
  #define   SEND_POSTED       2  
   
  typedef   struct  
  {  
  SOCKET   sock;  
   
  }PER_HANDLE_DATA,*LPPER_HANDLE_DATA;  
   
  typedef   struct  
  {  
  OVERLAPPED   Overlapped;  
  WSABUF   DataBuf;  
  DWORD   RecvBytes;  
  CHAR   Buffer[DATA_BUFSIZE];  
  UINT   OperationType;     //1=RECV_POSTED     2=SEND_POSTED      
  }PER_IO_OPERATION_DATA,*LPPER_IO_OPERATION_DATA;  
   
  //工作线程如下:  
  UINT   IOCPThread(LPVOID   lParam)  
  {  
  COverlappedDlg   *pDlg=(COverlappedDlg   *)lParam;  
   
  DWORD   BytesTransferred;  
  // OVERLAPPED   Overlapped;  
  LPPER_HANDLE_DATA   PerHandleData;  
  LPPER_IO_OPERATION_DATA   PerIoData;  
  DWORD   SendBytes,RecvBytes;  
  DWORD   Flags;  
   
  try  
  {  
  while(TRUE)  
  {  
   
   
  if(GetQueuedCompletionStatus(pDlg->m_CompletionPort,&BytesTransferred,(LPDWORD)&PerHandleData,(LPOVERLAPPED    
   
  *)&PerIoData,INFINITE)==0)  
  {  
  TRACE("\nGetQueuedCompletionStatus()   is   Error   ......");  
  return   0;  
  }  
   
   
  if(BytesTransferred==0)  
  {  
  TRACE("\n关闭了一个SOCKET");  
  closesocket(PerHandleData->sock);  
  GlobalFree(PerHandleData);  
  GlobalFree(PerIoData);  
  continue;  
  }  
   
  if(PerIoData->OperationType==RECV_POSTED)  
  {  
  PerIoData->RecvBytes   =   BytesTransferred;  
   
  Flags   =   0;  
  ZeroMemory(&(PerIoData->Overlapped),sizeof(OVERLAPPED));  
  PerIoData->OperationType   =   SEND_POSTED;  
  PerIoData->DataBuf.len=BytesTransferred;  
   
   
  WSASend(PerHandleData->sock,(LPWSABUF)&PerIoData->DataBuf,1,&SendBytes,Flags,&(PerIoData->Overlapped),NULL);          
   
  pDlg->PostMessage(WM_RECVDATA,0,(LPARAM)PerIoData->Buffer);  
   
  Flags   =   0;  
  ZeroMemory(&(PerIoData->Overlapped),sizeof(OVERLAPPED));  
  PerIoData->DataBuf.len   =   DATA_BUFSIZE;  
  PerIoData->DataBuf.buf   =   PerIoData->Buffer;  
  PerIoData->OperationType   =   RECV_POSTED;  
   
   
   
  WSARecv(PerHandleData->sock,&(PerIoData->DataBuf),1,&RecvBytes,&Flags,&(PerIoData->Overlapped),NULL);  
   
  }  
  if(PerIoData->OperationType==SEND_POSTED)  
  {  
  TRACE("\n发送数据成功");  
  }  
   
   
  }  
  }  
  catch(...)  
  {  
  TRACE("\n出错了!一个IOCPThread结束了......");  
  return   0;  
  }  
   
  TRACE("\n一个IOCPThread结束了......");  
  return   0;  
  }  
  问题点数:100、回复次数:18Top

1 楼phiger(phiger)回复于 2004-07-03 13:48:08 得分 27

if(PerIoData->OperationType==SEND_POSTED)  
  {  
  TRACE("\n发送数据成功");  
  }  
  这段代码不行,收到发送的事件通知并不意味着发送数据完成了,因为你是异步的,可能只发送成功了一部分  
  大概改成  
  if(PerIoData->OperationType==SEND_POSTED)  
  {  
                                                                          if   (BytesTransferred   <   PerIoData->DataBuf.len)  
                                                                          {   //   没发送完继续发送  
                                                                              PerIoData->DataBuf.buf   +=   BytesTransferred;  
    PerIoData->DataBuf.len   -=BytesTransferred;  
   
    WSASend(PerHandleData->sock,(LPWSABUF)&PerIoData->DataBuf,1,&SendBytes,Flags,&(PerIoData->Overlapped),NULL);          
  }  
  }Top

2 楼zxs0001(盛)回复于 2004-07-03 16:12:03 得分 0

To:   phiger(phiger)    
         
          1、为什么即使发送成功PerIoData->OperationType也不会等于SEND_POSTED?  
                if(PerIoData->OperationType==SEND_POSTED)  
                {      
                    ......      
                }  
                上面条件语句中的内容永远不会执行呀?  
   
          2、WSASend、WSARecv投递之前应该  
                        Flags   =   0;  
      ZeroMemory(&(PerIoData->Overlapped),sizeof(OVERLAPPED));  
                对吗?  
                但你上面补充的里面没有写呀?  
  Top

3 楼chenjieread(苦学VC++中...)回复于 2004-07-03 16:32:20 得分 2

你们   好厉害啊!!!羡慕Top

4 楼zxs0001(盛)回复于 2004-07-04 05:50:33 得分 0

大家帮忙看看呀!  
   
  1、为什么我WSASend()成功后,GetQueuedCompletionStatus()返回后PerIoData->OperationType还是等于SEND_POSTED  
  2、WSASend、WSARecv投递之前应该做些什么操作(对PerIoData及PerHandleData)  
  3、如果接收数据特别频繁(假设有20个客户端,每个客户端每秒有1000个数据到达,收到后还要应答),上面的那段代码是否还应该做适当修改才可胜任?  
   
   
  谢谢!Top

5 楼zxs0001(盛)回复于 2004-07-05 08:40:54 得分 0

怎么没人回答呀,是不是由于前两天是周末的原因呀!Top

6 楼Cowboy22(西部牛仔)回复于 2004-07-05 10:39:43 得分 30

if(PerIoData->OperationType==RECV_POSTED){  
      在这里你先是对PerIoData赋值;   ...   WSASend(),   紧跟着又对PerIoData赋值改写了PerIoData   ...WSARecv();   这样可能会导致出现你的问题。  
  }  
   
  所以建议PER_HANDLE_DATA结构应该对WSASend和WSARecv两个操作分别定义对应的Overlapped,DataBuf,   RecvBytes,   Buffer,   OperationType:  
  struct   IOContext{  
                    OVERLAPPED   Overlapped;  
  WSABUF   DataBuf;  
  DWORD   RecvBytes;  
  CHAR   Buffer[DATA_BUFSIZE];  
  UINT   OperationType;     //1=RECV_POSTED     2=SEND_POSTED      
  };  
  struct   PER_HANDLE_DATA{  
        SOCKET   socket;  
        IOContext   send,   recv;  
  };Top

7 楼zxs0001(盛)回复于 2004-07-05 11:59:56 得分 0

To:   Cowboy22(西部牛仔)    
           
          谢谢你的回答,我明白了  
           
          那对于我的第3个问题该怎么解决呀,像我上面的那段代码可以投入实际应用吗???万分感谢!  
  Top

8 楼zxs0001(盛)回复于 2004-07-05 17:34:47 得分 0

没有人关注了?????Top

9 楼zxs0001(盛)回复于 2004-07-06 12:20:09 得分 0

大家提提建议呀!!!!!Top

10 楼zxfvc(七品VC)回复于 2004-07-09 11:35:23 得分 4

我都还在迷惑中  
  <<windows   网络编程>>中好象还很多错呀,对于初学者来说有点不好懂。Top

11 楼zxs0001(盛)回复于 2004-07-10 15:15:30 得分 0

<<windows   网络编程>>看过了,还不是很懂呀!!!!Top

12 楼zxfvc(七品VC)回复于 2004-07-10 16:28:20 得分 0

昨天看了楼主的帖,回去做了一个程序,基本正常,但客户端只能接收到有限的内容(如果服务方发了大量的数据),可能就是上面的说的那样,没发完吧,我也不知道该怎样解决了,等高手来指点一下。Top

13 楼zxfvc(七品VC)回复于 2004-07-10 16:30:56 得分 0

请问楼主,你if(PerIoData->OperationType==RECV_POSTED)中的PerIoData->OperationType是怎样获得的?  
  Top

14 楼newlili(神啊,救救我吧!)回复于 2004-07-12 13:04:32 得分 2

学习ing...  
  等我会了,一定告诉你^_^Top

15 楼zxs0001(盛)回复于 2004-07-14 08:56:43 得分 0

To:zxfvc(七品VC)    
        对你说的  
      “请问楼主,你if(PerIoData->OperationType==RECV_POSTED)中的PerIoData->OperationType是怎样获得的?”  
        我也不是很清楚,改成像   Cowboy22(西部牛仔)     说的那样也许会好理解些  
   
        我也希望来个高手指点一下呀!!!Top

16 楼zxs0001(盛)回复于 2004-07-21 14:55:02 得分 0

问题没解决又有新的问题了  
   
          那位大虾,提点提点呀  
   
          判断出一个客户端断开之后,要不要清理与该客户端连接的套接字投递的操作,如果清理的话应该怎么清理!  
   
          只求提供思路就行了!  
  Top

17 楼ZHENG017()回复于 2004-07-21 16:00:48 得分 35

OperationType是自己指定的。  
  实际应用?还得继续改吧。在ms的sdk中有一个iocp的例子。  
  要清理,不然占用句柄数过多,程序崩溃。服务器程序最怕内存泄露,gdi,句柄泄露。Top

18 楼zxs0001(盛)回复于 2004-07-21 19:14:39 得分 0

To:   ZHENG017()    
           
          能给个清理的思路吗?谢谢!!Top

相关问题

  • 完成端口==高性能?? 对iocp感兴趣的都来看一下吧
  • 看一下,那错了?
  • 那错了?看一下
  • 那位仁兄帮忙看一下代码(端口通信)100分送!见着有分!!最好详细解释(我是用delphi的)
  • weblogic的问题, 那位给看一下.
  • 各位帮我看一下那错了
  • 帮我看一下那出毛病了
  • 帮忙看一下,很简单那
  • 帮个忙看一下那里错了!
  • 完成端口,WSASend

关键词

  • 客户
  • 数据
  • 线程
  • 解决
  • periodata
  • operationtype
  • perhandledata
  • wsasend
  • overlapped
  • databuf

得分解答快速导航

  • 帖主:zxs0001
  • phiger
  • chenjieread
  • Cowboy22
  • zxfvc
  • newlili
  • ZHENG017

相关链接

  • Visual C++类图书
  • Visual C++类源码下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
北京创新乐知广告有限公司 版权所有, 京 ICP 证 070598 号
世纪乐知(北京)网络技术有限公司 提供技术支持
Copyright © 2000-2008, CSDN.NET, All Rights Reserved
GongshangLogo