配置csocket 操作的超时时间

上传人:第*** 文档编号:31524350 上传时间:2018-02-08 格式:DOC 页数:8 大小:48.50KB
返回 下载 相关 举报
配置csocket 操作的超时时间_第1页
第1页 / 共8页
配置csocket 操作的超时时间_第2页
第2页 / 共8页
配置csocket 操作的超时时间_第3页
第3页 / 共8页
配置csocket 操作的超时时间_第4页
第4页 / 共8页
配置csocket 操作的超时时间_第5页
第5页 / 共8页
点击查看更多>>
资源描述

《配置csocket 操作的超时时间》由会员分享,可在线阅读,更多相关《配置csocket 操作的超时时间(8页珍藏版)》请在金锄头文库上搜索。

1、配置 Csocket 操作的超时时间最后修改 : 2005 年 8 月 24 日 本文的发布号曾为 CHS138692转载自 http:/ SetTimeOut(UINT uTimeOut)BOOL KillTimeOut()BOOL OnMessagePending()示例代码参考概要CSocket 操作,如 “接收”(Receive)、“发送”(Send) 和“连接”(Connect) 均是阻塞操作,即要等到操作成功执行完毕或套接字上出现错误后,对这些函数的调用才有返回结果。在某些情况下,操作可能永远不能成功完成,这将导致程序无限循环等待操作完成。一种解决方法是通过编程限制完成操作使用的时

2、间。本文将讨论这种方法。这种方法是设置定时,让它在操作时间过长时启动。此方法的关键在于处理定时器的方式。虽然操作是“阻塞的” ,但仍然可以处理到达的消息。如果通过使用 SetTimer 设置定时器,那么可以查找 WM_TIMER 消息,并在收到该消息时终止操作。该过程中涉及的主要函数有: Windows API 调用函数: :SetTimer MFC 函数: CSocket:OnMessagePending CSocket:CancelBlockingCall 为简单起见,可以在 Csocket 衍生类中封装该功能。警告:在进一步阅读本文之前,请注意在某些 MFC 版本中存在错误,会在试图使用

3、定时器并重叠 OnMessagePending 时引起问题。这一问题将在下面的 Microsoft Knowledge Base 文章中进行讨论: 137632 (http:/ 错误:定时器激活时未调用 OnMessagePending 本文仅适用于 Visual C+ 的 1.52、1.52b、2.1 和 2.2 版本。如果使用的是这些 Visual C+ 版本之一,则还需要实施所提供的变通解决方法。本文最后部分显示提供这种超时功能的类的示例代码。以下内容讲述由该类实现的函数。 BOOL SetTimeOut(UINT uTimeOut)调用此函数之后紧接着调用 CSocket 函数(如 R

4、eceive、Send 和 Accept)。uTimeOut 参数是以毫秒为单位指定的。之后,进行定时器的设置。如果设置定时器失败,那么函数返回 FALSE。有关详细情况,请参阅 SetTimer 函数的 Windows API 文档。 BOOL KillTimeOut()在完成阻塞操作后,必须调用此函数。此函数删除用 SetTimeOut 设置的定时器。如果调用 KillTimer 失败,则返回 FALSE。有关详细情况,请参阅 KillTimer 函数的 Windows API 文档。 BOOL OnMessagePending()这是一个虚拟回调函数,在等待操作完成时由 CSocket

5、类进行调用。此函数给您提供处理传入消息的机会。此实施过程检查用 SetTimeOut 调用函数设置的定时器的 WM_TIMER 消息。如果收到消息,则调用 CancelBlockingCall 函数。有关 OnMessagePending 和 CancelBlockingCall 函数详细的信息,请参阅 MFC 文档。请注意:调用 CancelBlockingCall 函数 将导致操作失败,而且 GetLastError 函数返回 WSAEINTR(表示操作中断)。下面是使用该类的一个例子: .CTimeOutSocket sockServer;CAcceptedSocket sockAcce

6、pt;sockServer.Create(777);sockServer.Listen();/ Note the following sequence:/ SetTimeOut/ / KillTimeOutif(!sockServer.SetTimeOut(10000)ASSERT(FALSE);/ Error Handling.for some reason, we could not setup/ the timer.if(!sockServer.Accept(sockAccept)int nError = GetLastError();if(nError=WSAEINTR)AfxMess

7、ageBox(No Connections Arrived For 10 Seconds);else; / Do other error processing.if(!sockServer.KillTimeOut()ASSERT(FALSE);/ Error Handling.for some reason the timer could not/ be destroyed.perhaps a memory overwrite has changed/ m_nTimerID?/ ./ / HEADER FILE/ class CTimeOutSocket : public CSocket pu

8、blic:BOOL SetTimeOut(UINT uTimeOut);BOOL KillTimeOut();protected:virtual BOOL OnMessagePending();private:int m_nTimerID;/ / END OF FILE/ / IMPLEMENTATION FILE/ BOOL CTimeOutSocket:OnMessagePending()MSG msg;if(:PeekMessage(&msg, NULL, WM_TIMER, WM_TIMER, PM_NOREMOVE)if (msg.wParam = (UINT) m_nTimerID

9、)/ Remove the message and call CancelBlockingCall.:PeekMessage(CancelBlockingCall();return FALSE; / No need for idle time processing.;return CSocket:OnMessagePending();BOOL CTimeOutSocket:SetTimeOut(UINT uTimeOut)m_nTimerID = SetTimer(NULL,0,uTimeOut,NULL);return m_nTimerID;BOOL CTimeOutSocket:KillT

10、imeOut()return KillTimer(NULL,m_nTimerID);CSOCKET 的超时设置和 UDP 发送接收使用 CSoket 多次了,但对于它的 block 模式的理解并不是很深入。昨天使用 csoket 的 udp 多发测试(server 接到数据后,需要通过某种方式将数据发送到client,使用 tcp 方式比较可靠,我一直这样用的,但是比较费时,需要逐一发送 ),发现了问题:1)create(),sendto(),receivefrom(). 2)其中,发送方一直定时发送数据无问题;3)而接收方,通过一个单独的接收线程实现( 注意:csocket 不能跨线程使用!

11、主线程中 socket create()后,detach()并将 sock 作为 lpvoid 传入接收线程 )。代码如下:/处理接收数据UINT CSockSvr:DealSvrRevData(LPVOID lParam).DWORD dwError;TCHAR cBuff1000;CString sIP;UINT uPort;for(;!pDlg-m_bExit;) :memset( cBuff,0,sizeof(cBuff) );/ 如果没有接到数据,一直等待。/ 阻塞模式的弊端:在退出时候,通过 CancelBlockingCallint iRst=SockSvr.ReceiveFro

12、m( cBuff,sizeof(cBuff),sIP,uPort,0 );if( iRst!=SOCKET_ERROR )CString sTemp=cBuff;TRACE1( _T(rn Rev Data: %srn),sTemp );elsedwError=GetLastError();TRACE1( _T(rn Rev Data Error code: %drn),dwError );:Sleep(200);return 0;问题:如果发送方没有数据,SockSvr.ReceiveFrom()会一致处于等待状态,导致整个处理接收线程的停止,如果用户需要退出/结束程序,无法正确释放资源(无

13、法关闭在线程函数重打开的 socket-不能跨线程操作 socket,无法关闭线程),造成系统 memory leak.针对这种问题,微软的解决办法是:http:/ ,经过测试,在 socket 进行 connect()的时候不好用。后来,结合微软的办法,我通过自定义的定时器,实现了 block 超时间后自动退出的功能#if !defined(AFX_TIMEOUTSOCK_H_19897A81_4EAF_4005_91FD_DC3047725139_INCLUDED_)#define AFX_TIMEOUTSOCK_H_19897A81_4EAF_4005_91FD_DC3047725139

14、_INCLUDED_#if _MSC_VER 1000#pragma once#endif / _MSC_VER 1000/ TimeOutSock.h : header file/*CSocket 操作,如接收 (Receive)、发送(Send) 和连接(Connect) 均是阻塞操作,即要等到操作成功执行完毕或套接字上出现错误后,对这些函数的调用才有返回结果。 某些情况下,操作可能永远不能成功完成,这将导致程序无限循环等待操作完成。一种解决方法是通过编程限制完成操作使用的时间。本文将讨论这种方法。 */ CTimeOutSock command targetclass CTimeOutS

15、ock : public CSocket/ Attributespublic:/ Operationspublic:CTimeOutSock();virtual CTimeOutSock();/ Overridespublic:/ ClassWizard generated virtual function overrides/AFX_VIRTUAL(CTimeOutSock)public:virtual BOOL OnMessagePending();/AFX_VIRTUAL/ Generated message map functions/AFX_MSG(CTimeOutSock)/ NOTE - the ClassWizard will add and remove member functions here./AFX_MSG/*/定时器设置 block 超时 不

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 办公文档 > 其它办公文档

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号