本人正在调试一个网络程序,调试过程中有很多迷糊的地方,其原因归结为对MFC 内部通过消息机制来调用各个类的函数不太理解,比如说,我做了一个对话框程序,当消息来临的时候,每次调用的是同一个对象的消息响应函数,还是每次都生成了一个对象来调用,我觉得好像在程序的声明周期类只生成了一个对话框的对象,但是,在对话框的响应函数里面我有调用了CAsyncSocket类的方法,每次调用的是同一个套接字对象还是不同的对象很迷糊!
对于CAsyncSocket的类的用法还不清楚,达人能否指点哈!主要是CAsyncSocket的用法,而且有什么地方要注意的,比如说,OnAccept的函数里面在调用的时候改是这样写
void CServerSock::OnAccept(int nErrorCode) 
{
// TODO: Add your specialized code here and/or call the base class
CServerSock Sock;
if(!Accept((CAsyncSocket&)Sock,NULL,NULL))
{
CString error;
error.Format("接收连接套接字失败:%d",GetLastError());
AfxMessageBox(error);
Close();
return;
}
DataSock.Add(&Sock);
CString text;
CWnd *pWnd=NULL;
pWnd=pView->GetDlgItem(IDC_STATIC_CONNNUM);
pWnd->GetWindowText(text);
CString num;
num.Format("%d",DataSock.GetSize());
m_nLinkNumber=DataSock.GetSize();
text="当前连接数:";
text+=num;
pWnd->SetWindowText(text);
    
CAsyncSocket::OnAccept(nErrorCode);
},还是这样写!
void CServerSock::OnAccept(int nErrorCode) 
{
// TODO: Add your specialized code here and/or call the base class
pDlg->OnAccept();
CAsyncSocket::OnAccept(nErrorCode);
}
不知道说清楚没!反正对这个很迷糊!

解决方案 »

  1.   

    建议现看看 windows网络编程技术 中
    WSAAsyncSelect的用法,然后再用封装后的代码。
      

  2.   

    看起来是很迷糊。“在对话框的响应函数里面我有调用了CAsyncSocket类的方法,每次调用的是同一个套接字对象还是不同的对象很迷糊!”
    这里你要明确一下,只能调用对象的方法,不能直接调用类的非静态的成员函数。所以如果你每次生成一个套接字对象就是调用不同的套接字;如果你每次访问同一个套接字对象(比如类的成员函数或者外部全局变量)就是同一个套接字。后面一个问题,在CASyncSocket::OnAccept中,其实要做两件事:
    一是判断是否可以接收连接。这个判断依据可以是对方的地址等,更多的是根据资源限制。初学者可以不考虑。
    二是接收连接,也就是调用Accept函数,并产生一个新的Socket对象,这个对象是用来和客户端通讯的。注意这个新的对象不是你现在的对象(*this),而是在Accept函数中产生的,并用这个新的对象来初始化你传入的对象,这也就是为什么第一个参数必须是一个引用。这个新的对象其实就是实现服务器、客户端通讯的主体,可以很简单,就是一个基本的CSocket或者CAsyncSocket对象,也可以是一个CSocket/CAsyncSocket继承类的对象。你的代码用了一个和监听类同样的类型,当然也可以,但是这样设计上这个类用于监听和通讯两个用途,就有些复杂,所以一般都是用两个不同的类分来来做。另外这个通讯用的Socket对象,一般来说都要保存下来用于后续的处理,所以可以放到一个数据结构中比如数组(上面说到判断能否接收连接,一种常用方法就是看连接数是否达到限制,也就是这个数组的限制)。
    那么你的第二段代码调用对话框类的一个函数,相当于在这个函数中做我上面说的两件事,也是可以的,和直接在CASyncSocket::OnAccept中做没有区别,就是一个逻辑分割的问题;但是因为最终还要调用Accept函数来建立连接,所以应该把这个对象的指针(this)传递过去,比如:
    pDlg->OnReceive(this, nErrorCode);
    注意这只是一种逻辑关系的转移,编程上没有区别。打字都累了,其实你可以看看MSDN上的示例代码。
      

  3.   

    还忘了说一句,在网络消息中(OnAccept)不要调用模态对话框,尽量用TRACE宏或者其他手段,也就是不要阻塞。