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

关于异步socket的回调

楼主borz(中五百万或是更多)2001-11-13 02:29:49 在 VC/MFC / 基础类 提问

急啊  
  遇到了一个问题,    
  MFC中异步socket,调用connect函数,有时(是偶尔)connect成功之后(server端已经打印出了request的tcp   address,证明已经connected),此异步socket不回调OnConnect函数,  
  之前的调用Connect()后lastError==10035,说明是异步调用方式  
  急啊!!!!!!!!!!!!!!  
  问题点数:135、回复次数:33Top

1 楼ShyWJB(家宝)回复于 2001-11-13 03:16:05 得分 0

我也正在做这样一个程序,可惜我才开始学,关注Top

2 楼sizhi(人在江湖飘啊~,哪能不挨刀啊~~)回复于 2001-11-13 08:27:14 得分 0

唉..无能为力,关注!!Top

3 楼evelan(醉猫)回复于 2001-11-13 08:36:53 得分 135

不能根据connect函数的返回值判断,重载OnConnect   在OnConnect中判断nError的值可得知成功是否Top

4 楼borz(中五百万或是更多)回复于 2001-11-13 08:46:21 得分 0

to醉猫:是啊我得一connect的反回值为WSAEWOULDBLOCK,这说明这是一个异步的操作,而我早已重载了OnConnect函数,但有时(我是说有时)系统却不回调这个onconnectTop

5 楼liuyinfeng(向你飞翔)回复于 2001-11-13 09:41:22 得分 0

hi  
  不知道您使用的是不是CSocket类,对于OnConnect在CSocket类里有点说法,别的就应该没什么了。能说的详细点吗?Top

6 楼DeadWolf(三角小眼睛又邪又媚又笨又呆又奸又诈又色)回复于 2001-11-13 09:43:46 得分 0

如果网络有问题     或者connect   的IP地址不正确的话  
  OnConnect   可能会等待一个比较长的时间   超时以后才会来  
  Top

7 楼zx_sanjin(www.chmbook.com - CHM电子书网)回复于 2001-11-13 09:52:33 得分 0

还是用SDK吧,   代码量都差不多的~~~Top

8 楼xtky_limi(窗外细雨)回复于 2001-11-13 10:04:02 得分 0

无能为力,关注!!   Top

9 楼supperapplication(行星)回复于 2001-11-13 10:31:37 得分 0

在后面加上这个试试:CAysncSocket::AsyncSelect(FD_CONNECT   );Top

10 楼zj_ok(zj_ok)回复于 2001-11-13 11:03:47 得分 0

有一个问题OnConnect是在accept之前还是之后调用?Top

11 楼eggplant(拉拉)回复于 2001-11-13 11:19:30 得分 0

关键是你的客户端Socket有没有机会处理FD_CONNECT事件?你的程序是不是进入了死循环而不能响应这个事件?Top

12 楼superdreamer(只懂一点点!)回复于 2001-11-13 11:26:12 得分 0

把你的代码贴出来,大家一起讨论Top

13 楼borz(中五百万或是更多)回复于 2001-11-13 11:57:23 得分 0

我把情况给大家说说  
   
  我后来跟踪到里面去了,  
  发现实际上connect成功时CAsyncSocket::DoCallBack(。。。)  
  他走的是case   FD_READ:即read   buffer有用,而不是FD_CONNECT  
   
  我的处理流程是这样的:  
  1:connect,   2:send   ,3:receive   第3步如果出错了或是结果不对,服务器就会关闭当前  
  socket,同时还会向客户端返回错误号,而我在客户端会根据返回的错误号,决定是否重新连接,然后再发送相应的请求,现在就是在重发请求之前的连接出了这个问题  
   
  下面是我连接的部分代码  
  m_Socket是类中的成员变量  
  m_Socket.Close();  
  if(m_Socket.Open(bp3_App->m_SrvAddr,bp3_App->m_SrvPort,error))  
        return   TRUE;  
  else  
  {  
        ....  
  }  
   
   
  下面是socket的代码  
  BOOL   CBPSocket::Open(CString   host,unsigned   short   port,CString&   msg)  
  {  
  BOOL   ok   =   FALSE;  
  HOSTENT   *lpHost;  
  SOCKADDR_IN   sockaddr_in;  
  //SetSockOpt(IPPROTO_TCP,&bp3_NetworkTimeout,sizeof(UINT),SO_RCVTIMEO);  
  lpHost   =   gethostbyname(host);  
  if(lpHost!=NULL)  
  {  
  if(!Create())  
  msg.Format("Create   Socket   object   error,   error   code:%d",GetLastError());  
  else  
  {  
  sockaddr_in.sin_family   =   AF_INET;  
  sockaddr_in.sin_port   =   htons(port);  
  sockaddr_in.sin_addr.s_addr=((LPIN_ADDR)lpHost->h_addr)->s_addr;  
  AsyncSelect(FD_READ   |   FD_CLOSE   |   FD_CONNECT);  
  UINT   r   =   Connect((SOCKADDR*)(&sockaddr_in),sizeof(SOCKADDR));  
  DWORD   lastError   =   GetLastError();  
  #ifdef   BP3_SOCKET_LOGFILE  
  CString   str1;  
  str1.Format("\r\nCall   Connect(),   lastError:%d",lastError);  
  m_logFile.Write(str1,str1.GetLength());  
  #endif  
  if(!r   &&   lastError==WSAEWOULDBLOCK)  
  ok   =   TRUE;  
  else  
  msg.Format("Failed   to   connect   with   server:'%s',error   code:%d",host,GetLastError());  
  }  
  }  
  else  
  msg.Format("Couldn't   resolve   host   name   '%s'",host);  
  return   ok;  
  }  
   
   
  void   CBPSocket::OnConnect(int   nErrorCode)  
  {  
  #ifdef   BP3_SOCKET_LOGFILE  
  CString   str1;  
  str1.Format("\r\nOnConnect(),   nErrorCode:%d",nErrorCode);  
  m_logFile.Write(str1,str1.GetLength());  
  #endif  
  bp3_App->GetDefDoc()->OnConnect(nErrorCode);  
  CAsyncSocket::OnReceive(nErrorCode);  
  }Top

14 楼liuyinfeng(向你飞翔)回复于 2001-11-13 12:40:54 得分 0

您能否将if(!Create())改为(!Create(0,SOCK_STREAM,FD_READ   ¦   FD_CLOSE   ¦   FD_CONNECT));然后connect的地方就可以Connect("IP","端口").  
  这样试一下?Top

15 楼borz(中五百万或是更多)回复于 2001-11-13 12:57:05 得分 0

为什么要这样呢  
  BOOL   Create(   UINT   nSocketPort   =   0,   int   nSocketType   =   SOCK_STREAM,   long   lEvent   =   FD_READ   |   FD_WRITE   |   FD_OOB   |   FD_ACCEPT   |   FD_CONNECT   |   FD_CLOSE,   LPCTSTR   lpszSocketAddress   =   NULL   );  
  其缺省的不就是可用的吗?  
  Top

16 楼liuyinfeng(向你飞翔)回复于 2001-11-13 13:47:58 得分 0

hi,  
  是的,说句心里话你的代码我还没看出什么问题,上一个问题只不过换一种我认为比较保险的方式。  
  再次问一下,是不是你再次open的时候,onconnect的代码没有执行?  
  关于LPIN_ADDR稍有疑问,可否改成inet_addr(写死的地址),然后后面的能注则注,试验一下?Top

17 楼liuyinfeng(向你飞翔)回复于 2001-11-13 13:59:57 得分 0

还有,能不能先Create,然后在open一下,m_Socket在open函数中自己调用create,就是自己创建自己是否可行?虽然感觉应该可以,但还是保险一下。Top

18 楼borz(中五百万或是更多)回复于 2001-11-13 15:11:03 得分 0

是的,再次open时onconnect不回调,就是这个毛病Top

19 楼supperapplication(行星)回复于 2001-11-14 09:58:32 得分 0

你可以在CAsyncSocket::receive()或者send()之后,加上CAysncSocket::AsyncSelect(FD_CONNECT   );   我原来也有类似的错误,就是这样解决的。Top

20 楼borz(中五百万或是更多)回复于 2001-11-14 21:18:36 得分 0

我这样试过了,可在win98   中文下,会造成onconnect的多次响应,2000下不会Top

21 楼borz(中五百万或是更多)回复于 2001-11-14 21:26:41 得分 0

现在我通过改用指针访问搞掂了,即每次  
  m_pSocket   =   new   ....  
  m_pSocket->...  
   
  用完后  
  m_pSocket->Close();  
  delete   m_pSocket;  
  m_pSocket   =   NULL;  
   
  用一个同行的话说,"感觉这样放心一些"  
  虽然这样,但我还是不能确定最根本的原因,请大家继续帮助Top

22 楼supperapplication(行星)回复于 2001-11-14 21:59:11 得分 0

我不知道win98下会怎么样?我这里没有98。Top

23 楼supperapplication(行星)回复于 2001-11-14 22:01:37 得分 0

把这句话去掉AsyncSelect(FD_READ   ¦   FD_CLOSE   ¦   FD_CONNECT);  
  放在recv之后。  
  Top

24 楼borz(中五百万或是更多)回复于 2001-11-14 22:58:13 得分 0

为什么呢?Top

25 楼amoroso(鼠标)回复于 2001-11-14 23:29:07 得分 0

学习Top

26 楼iconlee()回复于 2001-11-15 02:45:40 得分 0

学习Top

27 楼kenthuang()回复于 2001-11-16 12:49:40 得分 0

        socket连接在close()之后不一定就立即关闭。如果close()之后立即调用open(),有可能还是以同一socket与对端连接,此时自然也不会有OnConnect事件发生。Top

28 楼walk21cn()回复于 2001-11-16 13:00:28 得分 0

建议使用winsock   event   写,不要用mfc的类,不灵活Top

29 楼borz(中五百万或是更多)回复于 2001-11-17 11:14:15 得分 0

kenthuang似乎说到点子上了,但我还有一个疑问,后来我在close之前将他设为  
  阻塞工作方式,然后再close,难道这也不能保证close完全吗?   在这种情况下偶尔也会上现上  
  面的错误Top

30 楼sunyee(sunyee)回复于 2001-11-18 13:00:45 得分 0

我在上面的贴子中看到:  
        现在我通过改用指针访问搞掂了,即每次  
        m_pSocket   =   new   ....  
        m_pSocket->...  
   
        用完后  
        m_pSocket->Close();  
        delete   m_pSocket;    
        m_pSocket   =   NULL;  
  你这样做的用意可能是:在Close一个SOCKET后接着又想用它。(?)  
  如果是这样的话,可以这样做:  
  用的时候:  
    m_pSocket->Create();  
    m_pSocket->Connect(,);  
    .....  
  用完后:  
    m_pSocket->Close();  
  在OnClose()中:  
    Detach();  
  以后要再用的话,只要调上面的“用的时候”的代码即可,而无需new->delete->new->...  
  这是我的看法。Top

31 楼elic(michael)回复于 2001-11-18 21:57:38 得分 0

用CAsyncSocketTop

32 楼borz(中五百万或是更多)回复于 2001-11-21 11:26:14 得分 0

to:sunyee  
  我的确是想在close后继续使用,但现实是close后我必须马上调用create,然后connect来创建新的连接。  
  我怀疑这样会造成socket回调的的混乱(因为在调用create之前onclose回调还根本没有产生),我看内裤里面的回调入口代码他是基于一个集合类来实现管理两种链表的,一个用来装所有已经death的,另一个装正在工作的。   出于这个担心,我后来就干脆用new操作来产生新的地址,那是无论无何不会出现冲突了。  
  欢迎继续探讨:)  
   
  Top

33 楼javanew(我是java新手)回复于 2002-08-04 15:37:51 得分 0

222333Top

相关问题

  • 异步socket问题
  • socket 同步 or 异步?
  • socket异步传输数据
  • 异步方式socket问题
  • 异步socket通信问题
  • 异步Socket关闭出错
  • 关于异步Socket传输问题
  • 关于异步socket的小问题
  • 关于异步Socket的一些疑问。
  • Socket 异步 关闭问题 急用!!

关键词

  • win98
  • 函数
  • 代码
  • 连接
  • socket
  • 客户
  • psocket
  • onconnect
  • 调用
  • fd

得分解答快速导航

  • 帖主:borz
  • evelan

相关链接

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

广告也精彩

反馈

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