MFC CSocket和CAsyncSocket的连接

MFC CSocket和CAsyncSocket的连接

flyfish 2015-1-31

CSocket的Connect是阻塞的。

所以代码类似

if(!Connect())

{

}

判断成功还是失败

CAsyncSocket的Connect是非阻塞的

当调用CAsyncSocket::Connect连接一个服务器

虽然CAsyncSocket::Connect函数返回值是BOOL类型,

但代码不是

if(!Connect())

{

}

当连接操作完成,完成(complete)!=成功(successful ),应用程序将接收到OnConnect消息

所以需要重载OnConnect ,要在void 派生类::OnConnect(int nErrorCode)判断参数nErrorCode判断成功还是失败。

如果该类是派生于CSocket,也想要在OnConnect里判断

看源码

_AFXSOCK_INLINE BOOL CAsyncSocket::Connect(const SOCKADDR* lpSockAddr, int nSockAddrLen)
	{ return ConnectHelper(lpSockAddr, nSockAddrLen); }
BOOL CAsyncSocket::ConnectHelper(const SOCKADDR* lpSockAddr, int nSockAddrLen)
{
	return connect(m_hSocket, lpSockAddr, nSockAddrLen) != SOCKET_ERROR;
}
BOOL CAsyncSocket::Connect(LPCTSTR lpszHostAddress, UINT nHostPort)
{
	USES_CONVERSION_EX;

	ASSERT(lpszHostAddress != NULL);

	if (lpszHostAddress == NULL)
	{
		WSASetLastError (WSAEINVAL);
		return FALSE;
	}

	SOCKADDR_IN sockAddr;
	memset(&sockAddr,0,sizeof(sockAddr));

	LPSTR lpszAscii = T2A_EX((LPTSTR)lpszHostAddress, _ATL_SAFE_ALLOCA_DEF_THRESHOLD);
	if (lpszAscii == NULL)
	{
		WSASetLastError(ERROR_NOT_ENOUGH_MEMORY);
		return FALSE;
	}

	sockAddr.sin_family = AF_INET;
	sockAddr.sin_addr.s_addr = inet_addr(lpszAscii);

	if (sockAddr.sin_addr.s_addr == INADDR_NONE)
	{
		LPHOSTENT lphost;
		lphost = gethostbyname(lpszAscii);
		if (lphost != NULL)
			sockAddr.sin_addr.s_addr = ((LPIN_ADDR)lphost->h_addr)->s_addr;
		else
		{
			WSASetLastError(WSAEINVAL);
			return FALSE;
		}
	}

	sockAddr.sin_port = htons((u_short)nHostPort);

	return Connect((SOCKADDR*)&sockAddr, sizeof(sockAddr));
}
BOOL CSocket::ConnectHelper(const SOCKADDR* lpSockAddr, int nSockAddrLen)
{
	if (m_pbBlocking != NULL)
	{
		WSASetLastError(WSAEINPROGRESS);
		return  FALSE;
	}

	m_nConnectError = -1;

	if (!CAsyncSocket::ConnectHelper(lpSockAddr, nSockAddrLen))
	{
		if (GetLastError() == WSAEWOULDBLOCK)
		{
			while (PumpMessages(FD_CONNECT))
			{
				if (m_nConnectError != -1)
				{
					WSASetLastError(m_nConnectError);
					return (m_nConnectError == 0);
				}
			}
		}
		return FALSE;
	}
	return TRUE;
}

如果是CAsyncSocket::Connect

调用的是CAsyncSocket::Connect -》CAsyncSocket::ConnectHelper

如果是CSocket Connect时

CAsyncSocket::Connect -》CSocket::ConnectHelper 在这里产生了阻塞

阻塞与非阻塞的区别就在ConnectHelper

如果想要CSocket的派生类更改为CAsyncSocket的连接方式

只要在派生类重载ConnectHelper 和 OnConnect

声明
virtual BOOL ConnectHelper(const SOCKADDR* lpSockAddr,int nSockAddrLen);
virtual void OnConnect(int nErrorCode);

实现
BOOL 派生类::ConnectHelper(const SOCKADDR* lpSockAddr,int nSockAddrLen)
{
	return connect(m_hSocket, lpSockAddr, nSockAddrLen) != SOCKET_ERROR;
}

void 派生类::OnConnect(int nErrorCode)
{
}

时间: 2024-10-10 08:09:24

MFC CSocket和CAsyncSocket的连接的相关文章

静态MFC CSocket CAsyncSocket map_pp.cpp错误

静态MFC,在线程中使用SOCKET,发生错误: Debug Assertion Failed!Program:...File:f:\rtm\vctools\vc7libs\ship\atlmfc\src\mfc\map_pp.cppLine:179 这是MFC的一个BUG,在6.0中就发现,可惜微软到VS2013还是没有修改,估计这个东西微软也要淘汰了,懒得改了,下面是MSDN的解决方法: When using MFC sockets in secondary threads in a sta

MFC CSocket AfxBeginThread PossMessage Menu 自定义消息

1 // StockServerDlg.h : 头文件 2 // 3 4 #pragma once 5 #include "afxwin.h" 6 7 UINT ThreadProc(LPVOID pParm); 8 9 struct threadInfo 10 { 11 char recvMsg[256]; 12 char sendMsg[256]; 13 HWND hWnd; //主窗口句柄,用于消息的发送 14 }; 15 16 // CStockServerDlg 对话框 17

VC ++ MFC activex 控件获取连接的VPN 信息

vc++  MFC 进行activex  控件的开发步骤就不用多写了,只是简单的说明一下方法,以及具体的代码: 使用的类库是 windows 系统的 rasapi32.dll 记住需要添加的头文件如下: #include <Windows.h>#include <Ras.h>#include <RasError.h>#pragma comment(lib, "rasapi32.lib") 代码如下: VARIANT_BOOL CsecurityCon

[转载]CAsyncSocket及CSocket注解

MFC疑难注解:CAsyncSocket及CSocket MFC对SOCKET编程的支持其实是很充分的,然而其文档是语焉不详的.以至于大多数用VC编写的功能稍复杂的网络程序,还是使用API的.故CAsyncSocket及CSocket事实上成为疑难,群众多敬而远之.余好事者也,不忍资源浪费,特为之注解. 一.CAsyncSocket与CSocket的区别 前者是异步通信,后者是同步通信:前者是非阻塞模式,后者是阻塞模式.另外,异步非阻塞模式有时也被称为长连接,同步阻塞模式则被称为短连接.为了更明

MFC下CSocket编程详解

MFC下CSocket编程详解 分类: C/C++2008-03-13 09:01 34465人阅读 评论(34) 收藏 举报 mfc编程socket服务器socketsstream MFC下CSocket编程详解: 1. 常用的函数和注意事项(详细的函数接口说明请查看MSDN): CSocket::Create 初始化(一般写服务器程序都不要用为好,用下面的 CSocket::Socket 初始化) CSocket::Socket初始化 CSocket::SetSockOpt 设置socket

MFC Socket

目 录 第1章 同步TCP通讯    1 1.1 同步通讯与异步通讯    1 1.2 同步通讯类    1 1.3 同步TCP通讯客户端    4 1.3.1 界面    4 1.3.2 界面类声明    4 1.3.3 界面类构造函数    5 1.3.4 连接服务器    5 1.3.5 写数据    6 1.3.6 读数据    6 1.3.7 断开连接    7 1.4 同步TCP通讯服务端    7 1.4.1 界面    7 1.4.2 界面类声明    8 1.4.3 CSock

VC2005从开发MFC ActiveX ocx控件到发布到.net网站的全部过程

开篇语:最近在弄ocx控件发布到asp.net网站上使用,就是用户在使用过程中,自动下载安装ocx控件.(此文章也是总结了网上好多人写的文章,我只是汇总一下,加上部分自己的东西,在这里感谢所有在网上发表相关内容的朋友们.) ActiveX控件用于Web的过程是将控件嵌入主页中,用户通过浏览器访问该主页时,将主页中的控件下载,并在用户机器上注册,以后就可在用户的浏览器上运行.控件下载一次后就驻留在用户本地机器上,下次再访问相同的主页时,可不再下载该控件,而是直接运行用户本地的控件.这里控件容器就是

MFC对Socket编程的支持

MFC对Socket编程的支持其实是很充分的,然而其文档是语焉不详的.以至于大多数用Visual C++编写的功能稍复杂的网络程序,还是使用其API的.故CAsyncSocket及CSocket事实上成为了疑难,群众多敬而远之.余好事者也,不忍资源浪费,特为之注解. 1.CAsyncSocket与CSocket的区别是前者是异步通信,后者是同步通信.前者是非阻塞模式,后者是阻塞模式.另外,异步非阻塞模式有时也被成为长连接,同步阻塞模式则被成为短连接. 为了更明白的讲清楚两者的区别.举个例子.设想

[activeX]VC2005开发MFC ActiveX ocx控件全过程[转]

ActiveX控件用于Web的过程是将控件嵌入主页中,用户通过浏览器访问该主页时,将主页中的控件下载,并在用户机器上注册,以后就可在用户的浏览器上运行.控件下载一次后就驻留在用户本地机器上,下次再访问相同的主页时,可不再下载该控件,而是直接运行用户本地的控件.这里控件容器就是浏览器,用户不需要通过浏览器调用控件的属性或方法.因此,开发面向Web的ActiveX控件比开发桌面的控件还要简单些,所复杂的是如何将该控件很好地嵌入主页,使用户能正常浏览.下面介绍这个问题. 一.        创建MFC