MFC网络编程
一、概念
1.同步方式与异步方式
同步方式:发送方不等接收方响应,便接着发送下一个数据包的通信方式
异步方式:发送方发出数据,等收到接收方发回的响应后,才发送下一个数据包的通信方式
2.阻塞与非阻塞方式
阻塞套接字:执行此套接字的网络调用时,直到成功才返回,否则一直阻塞在此网络调用上。例如,调用Receive函数读取网络缓冲区中的数据,如果没有数据到达,将一直挂在Receive函数调用上,直到读到一些数据,此函数调用才返回。
非阻塞套接字:执行此套接字的网络调用时,不管是否执行成功,都立即返回。例如,调用Receive函数读取网络缓冲区中的数据,不管是否读到数据都立即返回,而不会一直挂在此函数上。
在实际Windows网络通信软件开发中,异步非阻塞套接字是用得最多的。(C/S)就是异步非阻塞模式。CAsyncSocket就是一个异步类,它封装了异步非阻塞Socket的基本功能,而CAsyncSocke的派生类CSocket则提供了阻塞的工作方式。
二、Socket事件
在实际应用中,程序员一般不直接使用CAsyncSocket类,而是自己定义它的派生类,主要原因就是需要捕获Socket激活的事件,如Socket连接建立,数据接收完毕等。在CAsyncSocket类中,为响应各种事件,定义了一系列可重载的函数,包括OnAccept,OnClose,OnConnect,OnReceive,OnSend
事件 响应函数 事件描述
FD_ACCEPT OnAccept 通知侦听套接字,对方程序的连接请求正在等待被接受
FD_CLOSE OnClose 连接的另一端应用程序已经关闭它的Socket或者连接已丢失,收到此通知的Socket应该关闭
FD_CONNECT OnConnect 通知连接套接字,对方的连接已经完成,可以通过Socket发送或接收数据
FD_READ OnReceive 表示Socket连接的数据已经接收到,可调用Receive函数接收
FD_WRITE OnSend 表示通过Socket已经准备好发送数据,连接完成即可调用此函数
三、Socket事件的激发的控制
默认情况下,CAsyncSocket类会调用所有的可重载函数,而CSocket一个也不调用。在实际应用中,往往需要控制Socket对特定事件函数的调用,可采用如下两种方式实现对这些事件函数激发的控制。
1.通过CAsyncSocket类的Create函数控制
此方法只适合于CAsyncSocket类及其派生类。在CAsyncSocket类的Create函数中,其第三个参数lEvent为一个标志值,可以指明需要激发哪个事件,其可能取值及要激发的事件如上所示。
BOOL CASyncSocket::Create(UINT nSocketPort=0, int nSocketType = SOCK_STREAM,
long lEvent = FD_ READ|FD_ WRITE|FD_OOB|FD ACCEPT|FD_CLOSE|FD_CONNECT,
LPCTSTR 1pszSOCketAddress=NULL);
2.通过CAsyncSelect函数控制
该方法适用于CAsyncSocket和CSocket的派生类。用组合标记定义激发哪些事件。
调用AsyncSelect函数的典型代码可表示如下:
if (m_ sock .AsyncSelect(FD_ READ|FD_ CONNECT)==SOCKET_ ERROR);
{
//错误处理
}else
//成功后的代码
默认情况下,AsyncSelect函数激发所有的事件函数。如果想要关闭所有事件的激发,可以采用如下代码:
m_sock.AsyncSelect(0)
四、Socket信息的获取与处理
有时,应用程序需要知道Socket的状态信息,如对方程序的网络地址和端口、Socket是否处于阻塞状态等。
1.获取Socket的地址
当一个Socket与另一个程序的Socket连接后,通过调用GetPeerName函数,获取连接的程
序的网络地址和端口。GetPeerName函数的原型如下:
BOOL GetPeerName(CString& rPeerAddress,UINT& rPeerPort);
两个参数分别用于记录连接方的网络地址和端口。
典型的GetPeerName函数的调用方法如下:
CString sAddress;
UINT iPort;
if(SOCKET_ERROR == m_socket.GetPeerName(&sAddress,&iPort))
{
//错误错误处理代码
}else
{
//成功获取代码
}
如果采用无连接通信,可以使用GetSocketName函数获取本方Socket的网络地址和端口。其使用方法与GetPeerName函数相同。
2. Socket闭塞处理
使用CSocket类时,所有Socket通信函数自动闭塞所有线程处理,直到它完成为止。正如有连接通信实例中见到的,如果调用了Socket上的Connect函数,此函数直到连接完成和Socket超时后才能返回线程的控制。Accept, Receive和Send函数也是如此。如果需要在函数返回前中断它们,该如何处理呢?
相比CAsyncSocket类,CSocket类提供了属性函数IsBlocking,用来确定一个阻塞调用是否在进行;CancelBlockingCall函数,用来取消一个当前在进行中的阻塞调用;重载函数OnMessagePending,当等待完成一个阻塞调用时,调用此函数来处理悬而未决的消息。下面对这3个函数进行详细介绍。
(1).BOOL CSocket::IsBlocking():如果该套接字是阻塞的,则返回非零值;否则返回O.此成员函数用来确定一个阻塞的调用是否正在进行中。
(2)BOOL CSocket::OnMessagePending( ):如果消息被处理了,则返回非零值;否则返回O.重载这个函数来查找来自Windows的特别消息,并在套接字中对它们作出响应。这是一个高级的可重载函数。当套接字在转发Windows消息时,框架调用OnMessagePending来处理应用程序感兴趣的消息。
(3)void CSocket::CancelBlockingCall( ):此成员函数用来取消一个当前在进行中的阻塞调用。这个函数取消该套接字的任何未完的阻塞操作。
除了Accept,取消任何操作都会使该套接字处于一种不确定的状态。
MFC,TCP_Srv网络步骤
1.CAsyncSocket m_sockSend //声明一个发送套接字
CSocket m_SockListen //声明一个监听套接字
2.m_SockListen.Create(m_SrvPort,SOCK_STREAM,0);
3.m_SockListen.bind(m_SrvPort,m_strSrvAddr);
4.if(m_SockListen.Listen())
5.m_SockListen.Accept(m_sockSend) //当有连接进入时,才返回
6.int iSend = m_sockSend.Send(szSend,10,0);
MFC,TCP_Client步骤
1.CSocket m_SockReceive
2.if(m_SockReceive.Create())
3.m_SockReceive.Connect(m_strSvrIP,m_nSvrPort);
4.int iRecv = m_SockReceive.Receive(szRecv,sizeof(szRecv),0);
MFC,UDP_Srv步骤
1.CAsyncSocket m_socket
2.m_socket.Create.Create(m_SrvPort,SOCK_DGRAM,0);
3.m_socket.bind(m_SrvPort,m_strSrvAddr);
4.int iSend = m_socket.SendTo(szSend,sizeof(szSend),m_ClientPort,m_strClientIP,0);
MFC,UDP_Client步骤
1.CAsyncSocket m_socket
2.m_socket.Create(m_ClientPort,SOCK_DGRAM,0);
3.m_socket.bind(m_ClientPort,m_strClientAddr);
4.int iRecv = m_socket.RecvFrom(szRecv,sizeof(szRecv),m_SrvIP,m_strSvrPort,0);
MFC网络编程的更多相关文章
- 转:MFC网络编程学习
要学习好网路编程,主要看以下几个方面: 1.掌握概念,诸如:同步(Sync)/异步(Async),阻塞(Block)/非阻塞(Unblock)等. 2.在实际Windows网络通信软件开发中,异步非阻 ...
- 《转》MFC网络编程学习
原地址:http://www.cnblogs.com/renyuan/archive/2013/06/04/3117006.html要学习好网路编程,主要看以下几个方面: 1.掌握概念,诸如:同步(S ...
- MFC 网络编程 -- 总结
原文链接:http://www.cnblogs.com/lidabo/archive/2012/07/19/2598734.html 1.基于 TCP 的 socket 编程 /* 服务器端程序流程: ...
- MFC 网络编程中::connect返回-1问题
在MFC编写网络时遇到了::connect总是返回-1,但是与服务器可以进行接收和发送消息的操作. 原因是在进行连接的时候我没有进行初始化:::WSAStartup(w, &data);//动 ...
- CSocket类网络编程 MFC
Visual C++的MFC提供了CSocket类用来实现网络通信. 下面介绍VC++在Windows 95中实现Socket的 CSocket 类相关成员函数(这些成员函数实际上是从CAsyncSo ...
- VC++ 网络编程总结(一)
1.套接字编程原理 一个完整的网间通信进程需要由两个进程组成,并且只能用同一种高层协议.也就是说,不可能通信的一段用TCP,而另一端用UDP.一个完整的网络信息需要一个五元组来标识:协 ...
- 完毕port(CompletionPort)具体解释 - 手把手教你玩转网络编程系列之三
手把手叫你玩转网络编程系列之三 完毕port(Completion Port)具体解释 ...
- windows socket 网络编程
样例代码就在我的博客中,包含六个UDP和TCP发送接受的cpp文件,一个基于MFC的局域网聊天小工具project,和此小工具的全部执行时库.资源和执行程序.代码的压缩包位置是http://www.b ...
- C#网络程序设计(1)网络编程常识与C#常用特性
网络程序设计能够帮我们了解联网应用的底层通信原理! (1)网络编程常识: 1)什么是网络编程 只有主要实现进程(线程)相互通信和基本的网络应用原理性(协议)功能的程序,才能算是真正的网 ...
随机推荐
- Android的Bitmap和BitmapDrawable类解析-android学习之旅(六十)
使用简单图片 使用Drawable对象 bitmap和BitmapDrawable对象 package peng.liu.test; import android.app.Activity; impo ...
- Linux基本配置和管理 4 ---- Linux系统启动详解
1 系统启动的流程 BIOS -> MBR+boot code -> 执行引导程序: GRUB -> 加载内核 -> 执行init -> 运行runlevel 2 启动详 ...
- 百度地图 Android SDK - Hello Baidu Map
例如,给广大以下主要开发者介绍了如何使用百度地图Android SDK构造的主应用程序的地图! 第一步.创建Androidproject,将百度地图Android SDK的开发包导入到project对 ...
- 依赖注入及AOP简述(九)——单例和无状态Scope .
三.依赖注入对象的Scope及其生命周期 在前面的章节我们讲到,依赖注入容器之所以能够区别于以往的ServiceLocator等容器,是在于其不但能够自动构建多层次的.完整的依赖关系图,并且可以管理依 ...
- LinQ学习手册
LinQ : Language Integrated Query(语言集成查询); 1.以统一方式操作各种数据源,减少数据访问的复杂性. 优点在于封装了SQL语句,只对对象进行操作(增删改查),代码量 ...
- 关于constructor与 Prototype的理解
constructor:每一个函数的Prototype属性指向的对象都包含唯一一个不可枚举属性constructor,该属性的值是这么一个对象:constructor指向了它所在的构造函数Protot ...
- input的样式简介
<input type="text" autocomplete="off" placeholder="" x-webkit-speec ...
- 【转】jQuery on()选择器函数
on()函数用于为指定元素的一个或多个事件绑定事件处理函数. 此外,你还可以额外传递给事件处理函数一些所需的数据. 从jQuery 1.7开始,on()函数提供了绑定事件处理程序所需的所有功能,用于统 ...
- 反射消除String类对象的不可变特性
大家都知道,在JAVA中字符串一旦声明就不可改变,如果尝试修改字符串的内容,将会重新实例化一个新的字符串对象,这也是为了安全性和效率. 由于字符串在程序之中被大量使用,所以JAVA引入了一个字符串常量 ...
- Toolkit Pro学习--Toolbar的创建
一.新建Toolkit Pro应用程序 安装好Toolkit Pro后,打开VS2008,新建-项目-Toolkit Pro Application.如图1所示. 图1:Toolkit Pro创建窗口 ...