初用CAsyncSocket遇到的问题[总结]

5 篇文章 0 订阅


分类: 网络编程
2007-03-29 08:58 阅读( 968) 评论(0)
一直以来都不知道mfc关于网络通信的封装类有哪些~只看到过 WinInet和CSocket,前者功能太弱,而后者刚开始一直以为跟socket一样,然后断断续续啃了半年tcp/ip协议第三卷[实现],看了大堆的socket编程资料和程序,直到去用的时候才发现真的有点繁琐。而没看异步IO的时候,程序都是靠多线程的.winsock2的异步函数用起来也挺麻烦`还要自定义消息~传递消息什么的~~

    直到前两天才发现CAsyncSocket这个封装类(CSocket则是在CAsyncSocket基础上派生的一个同步阻塞Socket的封装类),找资料的时候关于它的详细资料应该是摘自《Windows网络编程》,更要哭的是这本书崇敬了好久一直没有找到~有一次特意跑到图书城去买~结果一看薄薄的一本(跟C++ Primer相比)要76大洋~~只好咽咽口水灰溜溜的回去了~~~这两天试着用了用~并且找了个网上的代码调试了一下~遇到相当多的问题,总结一下写出来~结论都是自我感觉的~因为调试的程序很少~又没有人告诉我~~也不好断定~有些还太清楚。所以事先声明::结论都是根据过程猜测的 哪里不对一定要告诉我     以免误人子弟哦

1。CAsyncSocket的派生类对象调用Create()函数的时候总是错误。

      解决:用GetLastError()返回错误信息10093,查MSDN为WSANOTINITIALISED, 关于Create()函数中的解释为这个函数调用之前必须成功调用AfxSocketInit(),在MyApp::InitInstance()中调用解决。

      结论:不知道是不是我个人的原因,我见到的其他人没有人提到要调用这个,我感觉CAsyncSocket既然封装了应该可以自己调用的。

2。调试《使用MFC快速实现网络编程CAsyncSocket》一文中的Echo程序,只能发送并返回一次。

    解决:断点跟踪客户端程序,OnSend()和OnReceiver()函数均可正常调用。服务器程序转发对象接收第一次数据后OnReceive()函数就不再调用。发现只是在监听对象OnAccept()函数中调用了一次AsyncSelect(FD_READ),找不到更好的方法,只好在对话框程序中加入了OnTimer()函数,每100毫秒调用一次转发对象的AsyncSelect(FD_READ)<之前要判断对象是否已经创建并且连接>。

   结论:本来一直以为一旦有数据到来系统能自动发送消息给CAsyncSocket类的对象窗口,而由此看来,还是要手工发送消息。也就是人工控制发送接受函数,只不过不会阻塞罢了。 哎~以前把它想的太“自动”了~~纠正观念~~~        [     事实上本来想的是对的,这里的解决方法实际上是把WSAAsyncSocket异步模型降了一层,变为select模式了。这个问题的真正原因后面提到    ]``

3。自己写一程序,在Dlg中添加一个自定义类,自定义类中声明了个一个CAsyncSocket的派生类,创建正常,可是连接无论如何也无法激活OnReceive()函数,甚至直接调用AsyncSelect()也无法激活任何相应函数。

   解决:使用网络监控软件来看Connect以后连接确实建立了,之后的send也返回了发送字节数,但是就是无法启动响应函数。跟踪后发现类中的回调函数docallback没有进入,自然也就没有了消息处理。而将CAsyncSocket的派生类在Dlg中声明,则所有函数工作正常。

   结论:其间看了些资料,CAsyncSocket的i/o模型是基于窗口消息的,而他本身有自己的socketWnd窗口,但是这个窗口是在AfxSocketInit()函数调用时建立的。而我将CAsyncSocket用于了自定义的一个类,中间也没有传递窗口,自然就无法进行消息处理了~也就是说CAsyncSocket和CSocket都不能在无窗口模式下使用。而关于第二个问题的结论我也彻头彻尾的错了~~在能正常使用的情况下,一旦有数据到来系统确实能自动发送消息给CAsyncSocket类的对象窗口

而要在无窗口模式下使用异步模型,别人推荐使用WSAEventSelect模型,下一步要看他了~~~

=============================================

CAsyncSocket是非阻塞的,也就是它经常会返回值。当连接时,它返回错误,并不是真的有错。你可以GetLastError()然后判断是否为WSAEWOULDBLOCK,如果是这样,你可以忽略它,事实上已经建立了连接。另外,你用CSOCKET类就不会出现这种情况。因为他是阻塞的。

如果是返回值为10035的话,代表该SOCKET不能立即返回,你应该在OnConnect中响应是否连接成功的消息。这不是连接不成功的问题。
10035的错误号并不代表错误。 10035就是传说中的 WSAEWOULDBLOCK
你应该派生CAsyncSocket类,或者CSocket类。从而你可以从基类中获得OnConnect,Onreceive,OnClose等许多事件,通过这些事件你才可能知道你的连接与数据传送是否正确。
一般Client端应该处理的事件是onconnect,onclose,onreceive(如果接收数据)。
Server端应处理onreceive,onclose,onreceive等。
注意,两端都要派生新类。从文档类中生成派生类的对象。
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值