CSocket详解

CSocket的用法
CSocket在CAsyncSocket的基础上,修改了Send、Recieve等成员函数,
帮你内置了一个用以轮询收发缓冲区的循环,变成了同步短连接模式。
短连接应用简单明了,CSocket经常不用派生就可以直接使用,但也
有些问题:
1、用作监听的时候
曾经看到有人自己创建线程,在线程中创建CSocket对象进行Listen、
Accept,若Accept成功则再起一个线程继续Listen、Accept。。。
可以说他完全不理解CSocket,实际上CSocket已经内置了多线程机制,
你只需要从CSocket派生,然后重载OnAccept:

//CListenSocket头文件
class CListenSocket : public CSocket
{
public:
CListenSocket(HWND hWnd=NULL);
HWND m_hWnd; //事件处理窗口
virtual void OnAccept(int nErrorCode);
};
//CListenSocket实现文件
#include "ListenSocket.h"
CListenSocket::CListenSocket(HWND hWnd){m_hWnd=hWnd;}
void CListenSocket::OnAccept(int nErrorCode)
{
SendMessage(m_hWnd,WM_SOCKET_MSG,SOCKET_CLNT_ACCEPT,0);
CSocket::OnAccept(nErrorCode);
}
//主线程
...
m_pListenSocket=new CListenSocket(m_hWnd);
m_pListenSocket->Create(...);
m_pListenSocket->Listen();
...
LRESULT CXxxDlg::OnSocketMsg(WPARAM wParam, LPARAM lParam)
{
UINT type=(UINT)wParam;
switch(type)
{
case SOCKET_CLNT_ACCEPT:
{
CSocket* pSocket=new CSocket;
if(!m_pListenSocket->Accept(*pSocket))
{
delete pSocket;
break;
}
...
}
...
}
}

2、用于多线程的时候
常看到人说CSocket在子线程中不能用,其实不然。实际情况是:
直接使用CSocket动态创建的对象,将其指针作为参数传递给子线程,
则子线程中进行收发等各种操作都没问题。但如果是使用CSocket的
派生类创建的对象,就要看你重载了哪些方法,假如你仅仅重载了
OnClose,则子线程中你也可以正常收发,但不能Close!
因为CSocket是用内部循环做到同步的,并不依赖各OnXxx,它不需
要与CSocketWnd交互。但当你派生并重载OnXxx后,它为了提供消息
机制就必须与CSocketWnd交互。当你调用AfxSocketInit时,你的主
线程会获得一个访问CSocketWnd的句柄,对CSocketWnd的访问是MFC
自动帮你完成的,是被隐藏的。而你自己创建的子线程并不自动具
备访问CSocketWnd的机制,所以子线程中需要访问CSocketWnd的操
作都会失败。
常看到的解决办法是不要给子线程传递CSocket对象指针,而是传递
SOCKET句柄,然后在子线程中创建CSocket临时对象并Attach传入的
句柄,用完后再Dettach并delete临时对象。俺没有这么干过,估计
是因为Attach方法含有获取CSocketWnd句柄的内置功能。
俺的解决方案还是使用自定义消息,比如俺不能在子线程中Close,
那么,俺可以给主线程发送一条消息,让主线程的消息处理函数来
完成Close,也很方便。

CSocket的运作流程
CSocket一般配合多线程使用,只要你想收发数据,你就可以创建一
个CSocket对象,并创建一个子线程来进行收发。所以被阻塞的只是
子线程,而主线程总是可以随时创建子线程去帮它干活。
由于可能同时有很多个CSocket对象在工作,所以你一般还要创建一
个列表来储存这些CSocket对象的标识,这样你可能通过在列表中检
索标识来区分各个CSocket对象,当然,由于内存地址的唯一性,对
象指针本身就可以作为标识。
相对CAsyncSocket而言,CSocket的运作流程更直观也更简单,至于
CSocketFile、CArchive之类的,似乎也不需要多说什么,就这样结
束吧。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值