




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、桂林电子科技大学计算机网络 C 实验报告辅导员成绩 签 名实验名称 聊天程序的设计 电子工程与自动化系测控技术与仪器专业 14008104 班第 实验小组 作者 张业标 学号 1400810427 同作者 实验日期 2016 年 12 月 日 辅导员意见 【实验目的】1、熟悉 Visual C+ 的基本操作;2、基本了解基于对话框的 windows 应用程序的编写过程;3、对于 Windows Socket 编程建立初步概念,并实现聊天程序的编写。 【实验要求】1、能编写基于对话框的 windows 应用程序;2、能用 Visual C+中的 MFC CSocket类,实现网络传输数据;3、制
2、作实用的局域网一对一聊天程序; 【实验原理】一、 Windows Socket 和套接口的基本概念网际协议( Internet Protocol , IP)是一种用于互联网的网络协议,已广为人知。它可以 广泛用于大多数计算机操作系统上, 也可用于大多数局域网 LAN(比如小型办公网络, 小型 宿舍网络)和广域网 WAN(例如互联网) 。从它的设计来看, IP 是一个无连接的协议,并不 能保证数据投递万无一失。两个上层协议(TCP和 UDP)依赖 IP 协议进行数据通信。如果希望在 Microsoft Windows 下通过 TCP和 UDP 协议建立网络应用程序, 则需要使用 Winsock
3、套接口编程技术。Socket套接口,就是指向传输提供者的句柄。 Win32 中,套接口不同于文件描述符,所以它 是一个独立的类型 SOCKET。 Windows Socket 描述并定义了一个 Microsoft Windows 的网 络编程界面,它是从 Unix Socket 的基础上发展而来的,为 Windows TCP/IP提供了一个 BSD 型的套接字规范,除与 4.3BSD Unix Socket完全兼容外,还包括一个扩充文件,通过一组附 加的 API 实现 Windows 式(即事件驱动) 的编程风格; 而 Winsock 则是在 Microsoft Windows 中进行网络应用
4、程序设计的接口。 Windows 在 Internet 支配域中的 TCP/IP协议定义了 Winsock 网络编程规范,融入了许多新特点。使用 Socket 的目的是使用户在网络协议上工作而不必 对该网络协议有非常深入的了解。此外,编写的程序还可被迅速地移植到任何支持的网络系统中去。Winsock 提供了一种可为指定传输协议打开、 计算和关闭会话的能力。 在 Windows 下, TCP/IP上层模型在很大程度上与用户的Winsock 应用有关; 换言之, 用户的 Winsock 应用控制了会话的方方面面,必要时,还会根据程序的需要格式化数据。套接口有三种类型:流式套接口、数据报套接口及原始
5、套接口。流式套接口定义了一种可靠的面向连接的服务(利用 TCP协议),实现了无差错无重复的顺序数据传输。数据报套接口定义了一种无连接的服务(UDP),数据通过相互独立的报文进行传输,是无序的,并且不保证可靠和无差错。 原始套接口允许对低层协议如 IP和 ICMP 直接访问,主要用于新的网络协议实现的测试等。无连接服务器一般都是面向事务处理,一个请求、一个应答就完成了客户程序与服务 程序之间的相互作用。套接口工作过程如下: 服务器启动,通过调用 socket( )建立一个套接口, 然后调用 bind( ) 将该套接口和本地网络地址联系在一起,再调用accept( )来接收连接。客户在建立套接口后
6、调用 connect( )和服务器建立连接。连接一旦建立,客户机和服务器之间就可以通过调用read( )和 write( )来发送和接受数据。 最后,待数据传送结束后, 双方调用 close( )关闭套接口。 在网络编程中,掌握端口的概念十分重要。端口:基于TCP/IP协议的网络中,计算机都分配有一个 IP地址,用一个 32 位二进制数来表示,正式的称呼是“ Ipv4地址”。客户机 需要通过 TCP或 UDP和服务器通信时,必须指定服务器的IP 地址和服务端口号。另外,服务器打算侦听接入客户机请求时,也必须指定一个 应特别小心,因为有些可用端口号是为“已知的” 议和超文本传输协议,即 FTP(
7、 21 号端口)和 即固定协议,采用的端口由“互联网编号分配认证 编号。IP 地址和一个端口号。在选择端口时,(即固定的)服务保留的,如文件传输协HTTP(一般为 8080 端口)。“已知的协议” ,(IANA)”控制和分配, RFC 1700中说明的从本质上说,端口可分为 3 类:“已知”端口、已注册端口、动态和(或)私用端口。(1)“已知”端口 01023,由 IANA 控制,是在 UNIX中为固定服务保留的。(2)已注册的端口 1024 49151,由 IANA 列出来的,供普通用户的普通用户进程或 程序使用。(3)动态和(或)私用端口 49152 65535.普通用户应选择 1024
8、49151 之间的已注册端口,从而避免端口号已被另一个应用或 系统服务所用。此外, 49152 65535 间的端口可自由使用,因为 IANA在这些端口上没有注 册服务。、 MFC 对 Socket 编程的封装类简介Microsoft Windows Class Library ( MFC)中提供了较高级封装的类来实现网络通信。图 4-1 给出了 CSocket 类的继承关系。CObjectCAsyncSocketCSocket图 4-1CAsyncSocket类封装了 Windows Sockets API 函数,提供了较低层的与 Windows Sockets 对话接口, 一般适用于有相当
9、水平的网络编程者使用, 可方便地进行低层的网络事件通知及 信息回叫控制等操作。CSocket 类派生于 CAsyncSocket,它继承了父类中一些常用易懂的Windows Sockets API函数, 并对 CAsyncSocket中低层的较难控制的一些 API函数或成员函数进行了处理, 使得网 络传输简捷易用, 同时它支持模块化的后台信息处理, 解决了 CAsyncScoket中较难克服的多 线程处理。下面介绍用 Visual C在 windows 中实现 Socket 类型成员函数 (这些成员函数实际上 是从 CAsyncSocket类继承来的) 。成员函数和参数说明:(1)BOOL C
10、reate(UNIT nsocketPort 0,int nSocketType=SOCK_STREAMl,o ng lEvent = FD_READ|FD_WRITE|FD_OOB|FD_ACCEPT|FD_CONNECT| FD_CLOSE, LPCTSTR lpszSocketAddress=NULL)该函数用来建立 Socket,如果函数成功,则返回非零值;否则返回值为0。其中:nSocketPort:为所选择的 socket 端口, 一般要大于 1023,如果该参数为 0,则由系统选 定一端口,默认值 0。nSocketType:为套接字类型 SOCK_STREAM或 SOCK_DG
11、RAM。SOCK_STREAM表示为 流套接字 (本实验使用基于 TCP连接的流套接字编程) ,SOCK_DGRAM表示为数据报套接字, 默认值为 SOCK_STREAM。lEvent :标识该 Socket 要完成哪种工作,默认值为 FD_READ|FD_WRITE| FD_OOB| FD_ACCEPT|FD_CONNECT| FD_CLO。SElpszSocketAddress:一个指向字符串的指针, 该字符串包含了被连接套接口的网络地址。 一个带点的数据,如“ ”,默认值为 NULL。注意: CSocket中, WinsockAPI 的初始化 ( socket)和
12、绑定(bind )两部分工作都完成了。( 2) BOOL Listen(int nConnectionBacklog=5) 该函数的作用是等待 Socket请求,如果调用成功, 则返回非零值;否则返回值为 0。Listen 仅对那些支持连接的套接字起作用,也就是SOCK_STREAM类型的套接字。在进程应答连接并把它放到等待队列时, 套接字被置成被动模式 ( passive mode)。本函数一般由那些一次可 以用多个连接的服务器使用(或任何需要接受连接的应用) 。nConnectionBacklog :表示等待队列的长度,默认值为最大值5,有效值为 15。( 3) BOOL Connect(
13、LPCTSTR lpszHostAddress,UINT nHostPort) 该函数的作用是提出连接请求。其中:lpszHostAddress:对象连接的套接字的网络地址、机器名,如.dn ,或以句点分隔的数字,如“ 00 ”。nHostPort :为接受请求进程的网络地址和Socket 端口号。注意: Connect 函数还有另一个版本: BOOL Connect(const SOCKADDR *lpSockAddr, int nSockAddrLen);具体用法可以参阅 MSDN Library 中关于 CAnyscSocket类的阐述。(
14、4) virtual void Close ()该函数的作用是关闭该 Socket。三、利用 CSocket 进行传输的辅助类简介1、CSocketFile类CSocketFile继承自 CFile类,用在基于 Windows Socket 的网络上传输数据。 首先,将一 个建立连接的 CSocket 对象实例作为参数进行初始化,然后,将已经初始化的 CSocket对象 连接到 CArchive 对象上,接着将数据串行化,以使用MFC系列来简化发送和接受数据,最终实现利用网络的 Socket 传输和本机上的流传输一样简单。成员函数: CSocketFile 用到的成员函数只有构造函数。CSoc
15、ketFile: CSocketFile( CSocket *pSocket, BOOL bArchiveCompatible= true ) ;其中: pSocket:连接到 CSocketFile 对象的套接口。bArchiveCompatible :指示该文件对象是否与一个 CArchive 对象一起使用。只有当希望 在单机方式下来使用这个 CSocketFile对象时, 才传递 FALSE。因为仅有 CSocketFile类实例本 身没有什么意义,所以通常将其置为TRUE。说明:此成员函数用来构造一个 CSocketFile 对象。当此对象超出范围或被删除时,它 的析构函数将使它自己从
16、插槽对象上分离。注意:一个 CSocketFile 对象也可以在没有 CAchive 对象的情况下作为一个(受限制的) 文件来使用。 缺省情况下, CSocketFile 构造函数的 bArchiceCompatible 参数是 TRUE,它表明 此文件对象与一个档案一起使用。要在没有档案的情况下使用该文件对象,则给 bArchiceCompatible 参数传递 FALSE。在“档案兼容”模式下,一个CSocketFile 对象可以提供更好的表现,并减少出现“死锁”的几率。2 、 CArchive 类CAchive类没有基类。 CArchive 允许以永久二进制(通常为磁盘存储)的形式保存一
17、个 对象的复杂网络, 它可以从永久存储中装载对象, 并在内存中重新构造它们。 使数据永久保 留的过程就叫做“串行化” 。一般可以把一个 CArchive 对象看作一个二进制流,可以将它和 输入流 iostream 类的用法进行比较。 CArchive 对象一般和一个文件类关联( CFile 类或 CSocketFile类)。输入输出流是加工处理 ASCII字符,而 CArchive 类的用处是高效、 无冗余地 处理二进制数据。在 CArchive 类中,重载了提取( )和插入( value; aroutvalue; aroutvalue;注意事项:利用 CArchive 类进行网络数据传输的操
18、作固然方便直观,但是如果编写的程序是和别人的程序进行通信的话,就要注意对方的程序是否也使用了 CArchive 类,否则 会造成数据相互不能识别。五、使用 CSocket 类的同步问题和解决方法 有了上面的理论基础,就可以自己设计实现网络通信了。可以做到基于阻塞发送和接 受二进制数据。例如:可以 Client 端发送数据, Server 端接收数据:Server 端: m_receive(void *lpBuf, int nBufLen, int nFlags=0) ;Clietn 端: m_client(const void *lpBuf, int nBufLen, int nFlags=0
19、) ; 接着我们再分析一下各个类中提到的常用方法的同步特性: Listen( .):执行后无论有无连接,立即返回。 Connect():如果服务器端有端口正在监听,则立即成功返回,如果没有,则过几秒 钟后将显示无法连接。Accept():Listen 函数返回后可以执行此函数,但是此函数是基于阻塞的,只要客户机 connect 连接并且端口正确,则立即成功返回并建立连接 ;若迟迟监听不到连接,则不 断阻塞,直到连接成功或者强行关闭。Send( ):调用后就将数据保存在 socket 缓冲区中,立即返回。Receive( ):和 Accept 一样的阻塞,直到能从 socket 缓冲区成功读取到
20、 nBufLen 长度 的数据。按照上述分析,读者可能会考虑这样的两个问题: (1)监听的时候,如果客户端迟迟没有连接,则监听方执行到Accept 则阻塞不能相应。(2)在用 Receive 接受数据时,若迟迟得不到发送的数据,也阻塞不能响应。 显然,带有这两个问题的软件是不能被接受的。CSocket类里的 OnReceive 和 OnAccept消息处理函数(继承自 CAsyncSocket类)可以解决上述两个问题,其原理是:( 1)OnAccept():Listen 过后,若监听到客户机有连接,则产生消息调用OnAccept(),一般可以在此函数里面调用 Accept 便可避免监听时的阻塞
21、。virtural void OnAccept (int nErrorCode ):nErrorCode 为套接字上最近的错误代码, 此成员 函数可用的错误代码有:0:函数成功地执行并返回。WSAENETDOWN:Windows Socket 检测到网络系统故障。说明由框架调用,通知监听套 接字现在可以调用 Accept 成员函数来接收挂起的连接请求(有 connect 请求进入)。( 2) OnReceive():建立连接后,若检测到 Socket 缓冲区里有数据到达,便自动调用 OnReceive(),在此函数里面使用 Receive 接收就可避免接受数据的阻塞。virtural void
22、 OnReceive ( int nErrorCode ): nErrorCode 为套接字上最近的错误代码,此成 员函数可用的错误代码有:0:函数成功地执行并返回。WSAENETDOWN:Windows Socket 检测到网络系统故障。说明由框架调用,通知套接字 缓冲区中有数据,可以调用成员函数 Receive 取出。【实验内容与步骤】 在上述实验原理的基础上,以点对点通信的聊天程序为例实现网络通信,客户机/ 服务器模式是 socket 点对点网络程序的典型模式。使用的面向连接的TCP连接套接字是 MFC 的典型方式。其实现步骤为:1、创建两个对话框程序,分别为服务器端和客户端;2、启动服
23、务器端程序;3、创建套接字后等待客户的连接;4、客户启动,创建套接字,然后和服务器连接;5、连接建立后,客户机和服务器可以通过建立的套接字连接进行信息通信。聊天工具设计目的 、需求1、 建立 MFC 工程2、 插入对话框右侧对话框,左侧工具栏一、设计对话框界面1.设置对话框属性2、静态文本控件 3.编辑控件 3.组框 4.单选框 5.复选框 6.列表框 7.组合框PS:更改控件的 ID 号和标题、为设计好的对话框添加类为对话框添加相应的类才能使用对话框)CChatDlg ,类名的第一个 C 字母代表一个“类( class)Classname 中出现 CChartDlg,表明类已经添加成功。3、 为对话框中的控件添加变量接步骤( 2),开始:点击 Member Variables 选项卡,表中列出 ID 控件,4、为所有控件添加变量如图所示:5、控件变量的意义:6、 CChatDlg.cpp 文件中对成员函数变量进行初始化CChatDlg:CChatDlg(CWnd* pParent /*=NULL*/) : CDialog(CChatDlg:IDD, pParent)/AFX_DATA_IN
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
评论
0/150
提交评论