mfc socket编程
|
socket编程用法---- 随着计算机网络化的深入,计算机网络编程在程序设计的过程中变得日益重要。由于C++语言对底层操作的优越性,许多文章都曾经介绍过用VC++进行Socket编程的方法。但由于都是直接利用动态连接库wsock32.dll进行操作,实现比较繁琐。其实,VC++的MFC类库中提供了CAsyncSocket这样一个套接字类,用他来实现Socket编程,是非常方便的。 ---- 本文将用一个Echo例程来介绍CAsyncSocket类的用法。 ---- 一. 客户端 ---- 1. 创建一个Dialog Based项目:CSockClient。 ---- 2. 设计对话框 ---- 去掉Ok和Cancle两个按钮,增加ID_Connect(连接)、ID_Send(发送)、ID_Exit(关闭)按钮,增加ListBox控件IDC_LISTMSG和Edit控件IDC_EDITMSG,并按下表在ClassWizard中为CCSockClientDlg类添加变量。 Control ID Type Member ---- 3. CAsyncSocket类用DoCallBack函数处理MFC消息,当一个网络事件发生时,DoCallBack函数按网络事件类型:FD_READ、FD_WRITE、FD_ACCEPT、FD_CONNECT分别调用OnReceive、OnSend、OnAccept、OnConnect函数。由于MFC把这些事件处理函数定义为虚函数,所以要生成一个新的C++类,以重载这些函数,做法如下: ---- 以Public方式继承CAsyncSocket类,生成新类MySock; ---- 为MySock类添加虚函数OnReceive、OnConnect、OnSend ---- 4. 在MySock.ccp中添加以下代码 #include "CSockClient.h" ---- 5. 在MySock.h中添加以下代码 public: ---- 6. 在MySock.ccp中重载各函数 MySock::MySock() MySock::~MySock() void MySock::OnReceive(int nErrorCode) void MySock::OnSend(int nErrorCode) void MySock::OnConnect(int nErrorCode) ---- 7. 新建对话框IDD_Addr,用来输入IP地址和Port;生成新类CAddrDlg。增加两个Edit控件:IDC_Addr、IDC_Port按下表在ClassWizard中为CAddrDlg类添加变量。 Control ID Type Member IDC_Addr CString m_Addr ---- 8. 在CSockClientDlg.ccp中添加代码 #include "AddrDlg.h" ---- 9. 双击IDD_CSOCKCLIENT_DIALOG对话框中的“连接”按钮,添加以下代码 void CCSockClientDlg::OnConnect() ---- 10. 添加Windows消息WM_TIMER响应函数OnTimer void CCSockClientDlg::OnTimer(UINT nIDEvent) ---- 11. 双击IDD_CSOCKCLIENT_DIALOG对话框中的“发送”按钮,添加以下代码 void CCSockClientDlg::OnSend() ---- 12. 双击IDD_CSOCKCLIENT_DIALOG对话框中的“关闭”按钮,添加以下代码 void CCSockClientDlg::OnExit() ---- CNewSocket::OnSend(int nErrorCode) ---- void CMyServerSocket::OnAccept(int nErrorCode) ---- ---- 一、TCP/IP 体系结构与特点 1、TCP/IP体系结构 TCP/IP协议实际上就是在物理网上的一组完整的网络协议。其中TCP是提供传输层服务,而IP则是提供网络层服务。TCP/IP包括以下协议:(结构如图1.1) (图1.1) IP: 网间协议(Internet Protocol) 负责主机间数据的路由和网络上数据的存储。同时为ICMP,TCP, UDP提供分组发送服务。用户进程通常不需要涉及这一层。 ARP: 地址解析协议(Address Resolution Protocol) RARP: 反向地址解析协议(Reverse Address Resolution Protocol) ICMP: 网间报文控制协议(Internet Control Message Protocol) TCP: 传送控制协议(Transmission Control Protocol) UDP: 用户数据报协议(User Datagram Protocol) FTP: 文件传输协议(File Transfer Protocol) SMTP: 简单邮件传送协议(Simple Mail Transfer Protocol) TELNET:终端协议(Telnet Terminal Procotol) HTTP: 超文本传输协议(Hypertext Transfer Procotol) 2、TCP/IP特点 TCP/IP协议的核心部分是传输层协议(TCP、UDP),网络层协议(IP)和物理接口层,这三层通常是在操作系统内核中实现。因此用户一般不涉及。编程时,编程界面有两种形式:一、是由内核心直接提供的系统调用;二、使用以库函数方式提供的各种函数。前者为核内实现,后者为核外实现。用户服务要通过核外的应用程序才能实现,所以要使用套接字(socket)来实现。 图1.2是TCP/IP协议核心与应用程序关系图。 (图1.2) 二、专用术语 1、套接字 套接字是网络的基本构件。它是可以被命名和寻址的通信端点,使用中的每一个套接字都有其类型和一个与之相连听进程。套接字存在通信区域(通信区域又称地址簇)中。套接字只与同一区域中的套接字交换数据(跨区域时,需要执行某和转换进程才能实现)。WINDOWS 中的套接字只支持一个域——网际域。套接字具有类型。 WINDOWS SOCKET 1.1 版本支持两种套接字:流套接字(SOCK_STREAM)和数据报套接字(SOCK_DGRAM) 2、WINDOWS SOCKETS 实现 一个WINDOWS SOCKETS 实现是指实现了WINDOWS SOCKETS规范所描述的全部功能的一套软件。一般通过DLL文件来实现 3、阻塞处理例程 阻塞处理例程(blocking hook,阻塞钩子)是WINDOWS SOCKETS实现为了支持阻塞套接字函数调用而提供的一种机制。 4、多址广播(multicast,多点传送或组播) 是一种一对多的传输方式,传输发起者通过一次传输就将信息传送到一组接收者,与单点传送 一、客户机/服务器模式 在TCP/IP网络中两个进程间的相互作用的主机模式是客户机/服务器模式(Client/Server model)。该模式的建立基于以下两点:1、非对等作用;2、通信完全是异步的。客户机/服务器模式在操作过程中采取的是主动请示方式: 首先服务器方要先启动,并根据请示提供相应服务:(过程如下) 1、打开一通信通道并告知本地主机,它愿意在某一个公认地址上接收客户请求。 2、等待客户请求到达该端口。 3、接收到重复服务请求,处理该请求并发送应答信号。 4、返回第二步,等待另一客户请求 5、关闭服务器。 客户方: 1、打开一通信通道,并连接到服务器所在主机的特定端口。 2、向服务器发送服务请求报文,等待并接收应答;继续提出请求…… 3、请求结束后关闭通信通道并终止。 二、基本套接字 为了更好说明套接字编程原理,给出几个基本的套接字,在以后的篇幅中会给出更详细的使用说明。 1、创建套接字——socket() 功能:使用前创建一个新的套接字 格式:SOCKET PASCAL FAR socket(int af,int type,int procotol); 参数:af: 通信发生的区域 type: 要建立的套接字类型 procotol: 使用的特定协议 2、指定本地地址——bind() 功能:将套接字地址与所创建的套接字号联系起来。 格式:int PASCAL FAR bind(SOCKET s,const struct sockaddr FAR * name,int namelen); 参数:s: 是由socket()调用返回的并且未作连接的套接字描述符(套接字号)。 其它:没有错误,bind()返回0,否则SOCKET_ERROR 地址结构说明: struct sockaddr_in 3、建立套接字连接——connect()和accept() 功能:共同完成连接工作 格式:int PASCAL FAR connect(SOCKET s,const struct sockaddr FAR * name,int namelen); SOCKET PASCAL FAR accept(SOCKET s,struct sockaddr FAR * name,int FAR * addrlen); 参数:同上 4、监听连接——listen() 功能:用于面向连接服务器,表明它愿意接收连接。 格式:int PASCAL FAR listen(SOCKET s, int backlog); 5、数据传输——send()与recv() 功能:数据的发送与接收 格式:int PASCAL FAR send(SOCKET s,const char FAR * buf,int len,int flags); int PASCAL FAR recv(SOCKET s,const char FAR * buf,int len,int flags); 参数:buf:指向存有传输数据的缓冲区的指针。 6、多路复用——select() 功能:用来检测一个或多个套接字状态。 格式:int PASCAL FAR select(int nfds,fd_set FAR * readfds,fd_set FAR * writefds, 参数:readfds:指向要做读检测的指针 writefds:指向要做写检测的指针 exceptfds:指向要检测是否出错的指针 timeout:最大等待时间 7、关闭套接字——closesocket() 功能:关闭套接字s 格式:BOOL PASCAL FAR closesocket(SOCKET s); 三、典型过程图 2.1 面向连接的套接字的系统调用时序图 2.2 无连接协议的套接字调用时序图 2.3 面向连接的应用程序流程图 Windows Socket1.1 程序设计 一、简介 Windows Sockets 是从 Berkeley Sockets 扩展而来的,其在继承 Berkeley Sockets 的基础上,又进行了新的扩充。这些扩充主要是提供了一些异步函数,并增加了符合WINDOWS消息驱动特性的网络事件异步选择机制。 Windows Sockets由两部分组成:开发组件和运行组件。 开发组件:Windows Sockets 实现文档、应用程序接口(API)引入库和一些头文件。 运行组件:Windows Sockets 应用程序接口的动态链接库(WINSOCK.DLL)。 二、主要扩充说明 1、异步选择机制: Windows Sockets 的异步选择函数提供了消息机制的网络事件选择,当使用它登记网络事件发生时,应用程序相应窗口函数将收到一个消息,消息中指示了发生的网络事件,以及与事件相关的一些信息。 Windows Sockets 提供了一个异步选择函数 WSAAsyncSelect(),用它来注册应用程序感兴趣的网络事件,当这些事件发生时,应用程序相应的窗口函数将收到一个消息。 函数结构如下:
参数说明: hWnd:窗口句柄 wMsg:需要发送的消息 lEvent:事件(以下为事件的内容)
例如:我们要在套接字读准备好或写准备好时接到通知,语句如下:
如果我们需要注销对套接字网络事件的消息发送,只要将 lEvent 设置为0 2、异步请求函数 在 Berkeley Sockets 中请求服务是阻塞的,WINDOWS SICKETS 除了支持这一类函数外,还增加了相应的异步请求函数(WSAAsyncGetXByY();)。 3、阻塞处理方法 Windows Sockets 为了实现当一个应用程序的套接字调用处于阻塞时,能够放弃CPU让其它应用程序运行,它在调用处于阻塞时便进入一个叫“HOOK”的例程,此例程负责接收和分配WINDOWS消息,使得其它应用程序仍然能够接收到自己的消息并取得控制权。 WINDOWS 是非抢先的多任务环境,即若一个程序不主动放弃其控制权,别的程序就不能执行。因此在设计Windows Sockets 程序时,尽管系统支持阻塞操作,但还是反对程序员使用该操作。但由于 SUN 公司下的 Berkeley Sockets 的套接字默认操作是阻塞的,WINDOWS 作为移植的 SOCKETS 也不可避免对这个操作支持。 在Windows Sockets 实现中,对于不能立即完成的阻塞操作做如下处理:DLL初始化→循环操作。在循环中,它发送任何 WINDOWS 消息,并检查这个 Windows Sockets 调用是否完成,在必要时,它可以放弃CPU让其它应用程序执行(当然使用超线程的CPU就不会有这个麻烦了^_^)。我们可以调用 WSACancelBlockingCall() 函数取消此阻塞操作。 在 Windows Sockets 中,有一个默认的阻塞处理例程 BlockingHook() 简单地获取并发送 WINDOWS 消息。如果要对复杂程序进行处理,Windows Sockets 中还有 WSASetBlockingHook() 提供用户安装自己的阻塞处理例程能力;与该函数相对应的则是 SWAUnhookBlockingHook(),它用于删除先前安装的任何阻塞处理例程,并重新安装默认的处理例程。请注意,设计自己的阻塞处理例程时,除了函数 WSACancelBlockingHook() 之外,它不能使用其它的 Windows Sockets API 函数。在处理例程中调用 WSACancelBlockingHook()函数将取消处于阻塞的操作,它将结束阻塞循环。 4、出错处理 Windows Sockets 为了和以后多线程环境(WINDOWS/UNIX)兼容,它提供了两个出错处理函数来获取和设置当前线程的最近错误号。(WSAGetLastEror()和WSASetLastError()) 5、启动与终止 使用函数 WSAStartup() 和 WSACleanup() 启动和终止套接字。 来自网络 实例 static void* listenconnect(void* param) fd_set watchset, listenset, clientset; if(!monitorworking) |
mfc socket编程的更多相关文章
- 基于MFC的socket编程
网络编程 1.windows 套接字编程(开放的网络编程接口)添加头文件#include<windows.h> 2.套接字及其分类 socket分为两种:(1)数据报socket:无连接套 ...
- 基于MFC的socket编程(异步非阻塞通信)
对于许多初学者来说,网络通信程序的开发,普遍的一个现象就是觉得难以入手.许多概念,诸如:同步(Sync)/异步(Async),阻塞(Block)/非阻塞(Unblock)等,初学者往往迷惑不清, ...
- 揭开Socket编程的面纱
对TCP/IP.UDP.Socket编程这些词你不会很陌生吧?随着网络技术的发展,这些词充斥着我们的耳朵.那么我想问: 1. 什么是TCP/IP.UDP? 2. Socket在哪里呢? 3. Sock ...
- Socket编程学习之道:揭开Socket编程的面纱
对TCP/IP.UDP.Socket编程这些词你不会非常陌生吧?随着网络技术的发展.这些词充斥着我们的耳朵. 那么我想问: 1. 什么是TCP/IP.UDP? 2. S ...
- 【转】揭开Socket编程的面纱
对TCP/IP.UDP.Socket编程这些词你不会很陌生吧?随着网络技术的发展,这些词充斥着我们的耳朵.那么我想问: 1. 什么是TCP/IP.UDP?2. Sock ...
- 转:MFC网络编程学习
要学习好网路编程,主要看以下几个方面: 1.掌握概念,诸如:同步(Sync)/异步(Async),阻塞(Block)/非阻塞(Unblock)等. 2.在实际Windows网络通信软件开发中,异步非阻 ...
- Socket编程(摘抄)
http://www.blogjava.net 例子代码就在我的博客中,包括六个UDP和TCP发送接受的cpp文件,一个基于MFC的局域网聊天小工具工程,和此小工具的所有运行时库.资源和执行程序.代码 ...
- Socket编程指南及示例程序
例子代码就在我的博客中,包括六个UDP和TCP发送接受的cpp文件,一个基于MFC的局域网聊天小工具工程,和此小工具的所有运行时库.资源和执行程序.代码的压缩包位置是http://www.blogja ...
- 《转》MFC网络编程学习
原地址:http://www.cnblogs.com/renyuan/archive/2013/06/04/3117006.html要学习好网路编程,主要看以下几个方面: 1.掌握概念,诸如:同步(S ...
随机推荐
- 你确定你是一个合格的.Net开发人员吗?
做.net开发已有近5年时间,自认掌握的知识比较全面.最近部门需要招人,今天抽空在网上看了一下,发现我了解的还是不够多啊.下面是我大致的罗列了一下作为一名.Net开发人员所需要掌握的只是.看看你是不是 ...
- Lesson 3: The Amazing New Mobile Web
Lesson 3: The Amazing New Mobile Web Article 1: This is Responsive by Brad Frost 各种响应式网站设计的资源. Artic ...
- oracle 中如何定位重要(消耗资源多)的SQL【转】
1.查看值得怀疑的SQL )||'%'load, s.executions executes, p.sql_text from(select address, disk_reads, executio ...
- XIB自定义视图的整理
- (void)setAppInfo:(AppInfo *)appInfo { _appInfo = appInfo; _icon.image = appInfo.image; _label.text ...
- Swift开发必备技巧:内存管理、weak和unowned
因为 Playground 本身会持有所有声明在其中的东西,因此本节中的示例代码需要在 Xcode 项目环境中运行.在 Playground 中可能无法得到正确的结果. 不管在什么语言里,内存管理的内 ...
- Jquery中dialog属性小记
代码如下: $('#dialogDiv').dialog( { hide:true, //点击关闭是隐藏,如果不加这项,关闭弹窗后再点就会出错. autoOpen:false, height:380, ...
- JavaScript 之 使用 XMLHttpRequest 上传文件
<div id="div1"> <input type="file" id="uploadfile" style=&quo ...
- bootstrap兼容IE8的一些注意
准备 bootstrap 3.3.5 jQuery 1.12.0 注意 支持html5 需要引入html5.js 支持placeholder 需要引入placeholder.js ie8 不支持 fo ...
- SpringMVC 文件上传配置,多文件上传,使用的MultipartFile(转)
文件上传项目的源码下载地址:http://download.csdn.net/detail/swingpyzf/6979915 一.配置文件:SpringMVC 用的是 的MultipartFil ...
- Cocos2d粒子系统二
粒子系统的属性: 粒子的发射速度 重力模式(模式A): 重力 方向 速度 +- 变动 切向加速度 +- 变动 径向加速度 +- 变动 半径模式(模式B): 开始半径 +- 变动 结束半径 +- 变动 ...