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)什么是网络编程 只有主要实现进程(线程)相互通信和基本的网络应用原理性(协议)功能的程序,才能算是真正的网 ...
随机推荐
- Apache启用GZIP压缩网页传输方法
一.gzip介绍 Gzip是一种流行的文件压缩算法,如今的应用十分广泛,尤其是在Linux平台.当应用Gzip压缩到一个纯文本文件时,效果是很明显的,大约能够降低70%以上的文件大小.这取决于文件里的 ...
- MVC3.0修改jquery.validate.unobtrusive.js实现气泡提示mvc错误
CSS部分 <style type="text/css"> .hide {display:none;} .poptip { position: absolute; to ...
- 你知道为什么Xcode6中Swift没有智能提示和自己主动补全功能吗 ?
你知道为什么Xcode6中Swift没有智能提示和自己主动补全功能吗 ? 长沙戴维营教育将为你解开这个巨大的谜团大BUG! http://www.ubuntucollege.cn/course/29/ ...
- UVA - 10574 Counting Rectangles
Description Problem H Counting Rectangles Input: Standard Input Output:Standard Output Time Limit: 3 ...
- VS单元测试入门实践教程
摘要:本教程不会介绍单元测试的基本理论知识,也不会和大家讨论在实际项目中是否需要写单元测试代码的问题.但是如果你此时想使用VS中的单元测试的工具来测试某个方法是否正确,可你又从来没真正实践过,那么本教 ...
- L10 数据入站、转发、出站流程
二 写出防火墙规则链之间的顺序也就是入站数据流向.转发数据流向.出站数据流向的过程 入站:PREROUTING→INPUT 数据包到达防火墙,由prerouting处理,判断是否修改地址 路由选择:判 ...
- Qt使用快捷键
在说快捷键之前先来说一个QtCreator调试的过程中经常发生的一个问题. 问题描述: 用QtCreator建立了一个纯C++的项目,但是在F5调试时,竟然提示ptrace不允许的操作,修改工程配置为 ...
- smarty模版使用php标签,获取模版变量!
<ul>{/foreach from=$A key=k item=val/}{/php/} $val = $this->_tpl_vars[val]; $date = substr( ...
- 5.7.2.2 min()和max()方法
Math对象还包含许多方法,用于辅助完成简单和复杂的数学计算. 其中,min()和max()方法用于确定一组数值中的最小值和最大值.这两个方法都可以接受任意多个数值参数,如下例子: var max = ...
- 关于在页面上执行sql语句
在页面上执行sql语句,首先在页面上顶一个文本域,让用户输入需要执行的sql语句. html代码如下: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML ...