VC6下MFC CBG兼容IPV6方法

1,271 阅读3分钟

VC6下MFC CBG兼容IPV6方法

在大学的时候开始接触.net,工作了才发现还有更古老的东西MFC(MFC源码的可读性很强),项目中需要改一个commander工具用于telnet连接, 写这一篇简单粗暴的以供以后自己查阅

操作步骤

1、拿到代码的时候自觉地打开了vs2013,build..., 不对,报了很多的语法错误, 查看报错信息BCGCB464.lib库文件没找到, 百度了下bcg是个啥, 哦。。。微软自带的组件库, 赶紧找一下4.6版本的。。。。?最久的是18版本的, 再看一下项目代码的更改日期。。。2001年。。。咋办捏,最后下了一个稳定版本的25, 好歹也是向下兼容的吧, tools ->option -> c/c++ lib、include文件路径加进去, 再来一把。。。。vc6的字符集和vs2013不兼容, 导致很多语法错误。。。。

2、实在没辙问了身边的大佬,貌似需要用VC6打开, VC6是个啥? 我记得大学第一节课老师给我们用的就是vc,好吧, 用win10自带的hyper-v装一下winxp, 顺利安装调试。。。

3、打开源代码看到这样一段

class EPTCSocket : public CAsyncSocket
{
// Attributes
public:
	enum
	{
		SOCK_BUF_RECV_LEN = 1024,

		SOCK_STATUS_IDLE = 0,
		SOCK_STATUS_CONNECTING = 1,
		SOCK_STATUS_WORK = 2,

		SOCK_EXT_MON_NONE = 0,
		SOCK_EXT_MON_CONNECT = 1,
	};


喔, 肯定是用了MFC下面的CAsyncSocket模块, 然后还是打开百度, 查看mfc支持ipv6的案例。。。。 看到的都是不支持。。。自己写。。。手撸。。。 然后我一看代码都用了CAsyncSocket的Create()、Connect()。。。重写模块的工作量有点大, 而且组件跟CAsyncSocket之间事件绑定也很严密, 咋办, 我毕竟是个pythoner,让我搞这个吃不消啊。。。

4、 都说wins开发有事找msdn, 打开看下吧。。。貌似木有,找官网文档去。。。 还真被我找到了,参考文档:docs.microsoft.com/zh-cn/windo… 之前的ipv4 用了sockaddr_in结构, 而ipv6则使用sockaddr_in6,ipv4中获取ip地址使用了gethostbyname函数, 而ipv6使用 getaddrinfo, 貌似getaddrinfo是兼容两者的, 只不过ai_family = AF_UNSPEC,既然这样我就测试下看看,咦???getaddrinfo未定义, 让我在百度下。。。

5、了解了, 我看了下我的SDK是4.2, 这TM也太老了吧。 我看了下最新支持VC6的SDK就是msdk_2003版本的了, 网上一顿搜找到一个版本的,注意了, 官网木有了,需要的私我!!!

安装步骤如下:

	1. 拷贝安装包所有文件到本地, 本地创建存放目标文件夹。
	2. 进入安装包文件夹执行:  PSDK-FULL  /目标文件夹。
	3. 在目标文件夹中找到setup.exe点击安装。
	4. 执行: 开始---程序---Microsoft Platform SDK for Windows XP SP2---Visual Studio Registration-----Register PSDK Directories with Visual Studio

6、升级完sdk之后呢, 开始看CAsyncSocket模块, 发现从创建socket开始就只支持ipv4,难怪都说不支持,往下看吧, 在Connect中重载了下, 到最后都是调用了CAsyncSocket::Connect(m_ai -> ai_addr, m_ai->ai_addrlen);, 那行吧, 我改一下试试看, 简单粗暴贴一下这部分的源代码

m_Host = lpszHostAddress;
CString tempStr;
m_Host = CString(lpszHostAddress);
m_Port = nHostPort;
m_Timeout = Timeout;

char tempPost[4];
_itoa(nHostPort, tempPost, 10);
struct addrinfo hints, *m_ai;
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
if(getaddrinfo(lpszHostAddress, tempPost, &hints, &m_ai) != 0){
	return false;	
}
//// 设置成异步接收方式
//	ret = CAsyncSocket::AsyncSelect(FD_CONNECT | FD_READ | FD_CLOSE);
	ret = CAsyncSocket::AsyncSelect(FD_READ | FD_CLOSE);
	if(!ret)
	ret = CAsyncSocket::AsyncSelect(FD_READ | FD_CLOSE);
    if(!ret)
	ASSERT(m_hSocket == INVALID_SOCKET);
// 自己创建socket赋值给m_hSocket
	m_hSocket = socket(m_ai->ai_family, m_ai->ai_socktype, m_ai->ai_protocol);
	if(m_hSocket == INVALID_SOCKET){
		return false;

	//// 设置状态标志
	m_Status = SOCK_STATUS_CONNECTING;

	}
	CAsyncSocket::AttachHandle(m_hSocket, this, FALSE);
	if(!AsyncSelect(63)){
		return false;
	}
	//// 连接服务器
	ret = CAsyncSocket::Connect(lpszHostAddress, nHostPort);
	if((ret == 0) && (GetLastError() != WSAEWOULDBLOCK))
		ret = CAsyncSocket::Connect(m_ai -> ai_addr, m_ai->ai_addrlen);
	if((ret == 0) && (GetLastError() != WSAEWOULDBLOCK)){
		return false;

8、看到了欣慰的一幕,搞定了。 对了, 测试之前肯定需要两台主机都配置ipv6 别忘了啊!!!

下班~~~~溜了溜了