网站导航免费论文 原创论文 论文搜索 原创论文 网学软件 学术大家 资料中心 会员中心 问题解答 原创论文 论文素材 设计下载 最新论文 下载排行 论文上传 在线投稿 联系我们
返回网学首页
网学联系
最新论文 推荐专题 热门论文 素材专题
当前位置: 网学 > 编程文档 > VC++ > 正文
SOCKET类的设计和实现
来源:Http://myeducs.cn 联系QQ:点击这里给我发消息 作者: 用户投稿 来源: 网络 发布时间: 12/10/15
下载{$ArticleTitle}原创论文样式
cket对象(捆绑在一起),指定本socket要通知的网络事件,并创建一个“socket窗口”来接收网络事件消息,最后,指定socket的本地信息。

下一步,是使用成员函数Connect连接远地主机,配置socket的远地信息。函数Connect类似于Bind,把指定的远地地址转换成SOCKADDR_IN对象表示的地址信息(包括网络字节序的转换),然后调用WinSock函数Connect连接远地主机,配置socket的远地端口和远地IP地址。


异步网络事件的处理

当网络事件发生时,“socket窗口”接收WM_SOCKET_NOTIFY消息,消息处理函数OnSocketNotify被调用。“socket窗口”的定义和消息处理是MFC实现的,这里不作详细的讨论。

OnSocketNotify回调CAsyncSocket的成员函数DoCallBack,DoCallBack调用事件处理函数,如OnRead、OnWrite等。摘录DoCallBack的一段代码如下:

switch (WSAGETSELECTEVENT(lParam))

{

case FD_READ:

{

DWORD nBytes;

//得到可以一次读取的字节数

pSocket->IOCtl(FIONREAD, &nBytes);

if (nBytes != 0)

pSocket->OnReceive(nErrorCode);

}

break;

case FD_WRITE:

pSocket->OnSend(nErrorCode);

break;

case FD_OOB:

pSocket->OnOutOfBandData(nErrorCode);

break;

case FD_ACCEPT:

pSocket->OnAccept(nErrorCode);

break;

case FD_CONNECT:

pSocket->OnConnect(nErrorCode);

break;

case FD_CLOSE:

pSocket->OnClose(nErrorCode);

break;


lParam是WM_SOCKET_NOFITY的消息参数,OnSocketNotify传递给函数DoCallBack,表示通知事件。

函数IOCtl是CAsyncSocket的成员函数,用来对socket的I/O进行控制。这里的使用表示本次调用Receive函数至多可以读nBytes个字节。

从上面的讨论可以看出,从创建socket到网络I/O,CAsyncSocket直接封装了低层的WinSock API,简化了WinSock编程,实现了一个异步操作的界面。如果希望某个操作是阻塞操作,则在调用Create时不要指定该操作对应的网络事件。例如,希望Connect和Send是阻塞操作,在任务完成之后才返回,则可以使用如下的语句:

pSocket->Create(0, SOCK_STREAM,

FR_WRITE|FR_OOB|FR_ACCEPT|FR_CLOSE);

这样,在Connect和Send时,如果是用户界面线程的话,可能阻塞线程消息循环。所以,最好在工作者线程中使用阻塞操作。


CSocket

如果希望在用户界面线程中使用阻塞socket,则可以使用CSocket。它在非阻塞socket基础之上实现了阻塞操作,在阻塞期间实现了消息循环。

对于CSocket,处理网络事件通知的函数OnAccept、OnClose、OnReceive仍然可以使用,OnConnect、OnSend在CSocket中永远不会被调用,另外OnOutOfBandData在CSocket中不鼓励使用。

CSocket对象在调用Connect、Send、Accept、Close、Receive等成员函数后,这些函数在完成任务之后(连接被建立、数据被发送、连接请求被接收、socket被关闭、数据被读取)之后才会返回。因此,Connect和Send不会导致OnConnect和OnSend被调用。如果覆盖虚拟函数OnReceive、OnAccept、OnClose,不主动调用Receive、Accept、Close,则在网络事件到达之后导致对应的虚拟函数被调用,虚拟函数的实现应该调用Receive、Accept、Close来完成操作。下面,就一个函数Receive来考察CSocket如何实现阻塞操作和消息循环的。

int CSocket::Receive(void* lpBuf, int nBufLen, int nFlags)

{

//m_pbBlocking是CSocket的成员变量,用来标识当前是否正在进行

//阻塞操作。但不能同时进行两个阻塞操作。

if (m_pbBlocking != NULL)

{

WSASetLastError(WSAEINPROGRESS);

return FALSE;

}

//完成数据读取

int nResult;

while ((nResult = CAsyncSocket::Receive(lpBuf, nBufLen, nFlags))

== SOCKET_ERROR)

{

if (GetLastError() == WSAEWOULDBLOCK)

{

//进入消息循环,等待网络事件FD_READ

if (!PumpMessages(FD_READ
  • 上一篇资讯: 用VC++遍历目录
  • 下一篇资讯: 鼠标屏幕取词原理
  • 网学推荐

    免费论文

    原创论文

    浏览:
    设为首页 | 加入收藏 | 论文首页 | 论文专题 | 设计下载 | 网学软件 | 论文模板 | 论文资源 | 程序设计 | 关于网学 | 站内搜索 | 网学留言 | 友情链接 | 资料中心
    版权所有 QQ:3710167 邮箱:3710167@qq.com 网学网 [Myeducs.cn] 您电脑的分辨率是 像素
    Copyright 2008-2015 myeducs.Cn www.myeducs.Cn All Rights Reserved
    湘ICP备09003080号