logo资料库

基于UDP局域网的聊天软件.pdf

第1页 / 共25页
第2页 / 共25页
第3页 / 共25页
第4页 / 共25页
第5页 / 共25页
第6页 / 共25页
第7页 / 共25页
第8页 / 共25页
资料共25页,剩余部分请下载后查看
局 域 网 聊 天 室 单位:南通大学计算机科学与技术学院 计 102 班 - 1 -
目 录 1.2.1、开发环境……………………………………………………………………3 1.2.2、硬件环境……………………………………………………………………3 1.2.3、软件环境……………………………………………………………………3 1.2.4、VC++6.0 简介………………………………………………………………3 1.2.5、Windows Sockets …………………………………………………………3 1、引言…………………………………………………………………………………………3 1.1、本文主要作用………………………………………………………………………3 1.2、开发平台与技术的选择及介绍 2、相关开发技术的说明 2.1、Windows 程序内部运行机制………………………………………………………3 2.1.1、API…………………………………………………………………………4 2.1.2、窗口与句柄…………………………………………………………………4 2.1.3、消息与消息队列……………………………………………………………4 2.1.3.1、消息…………………………………………………………………5 2.1.3.2、消息队列……………………………………………………………5 2.1.3.3、进队消息和不进队消息……………………………………………5 2.2、套接字(socket)的引入…………………………………………………………6 2.3、网络字节序…………………………………………………………………………6 2.4、Windows Sockets 的实现…………………………………………………………6 2.4.1、套接字的类型………………………………………………………………6 2.4.2、基于 TCP(面向连接)的 socket 编程……………………………………6 2.4.3、基于 UDP(面向无连接)的 socket 编程…………………………………6 2.4.4、相关函数……………………………………………………………………7 2.5、基于消息的异步套接字……………………………………………………………8 2.5.1、相关函数……………………………………………………………………8 3、总体设计……………………………………………………………………………………8 3.1、工作流程……………………………………………………………………………9 3.2、工作方式简介………………………………………………………………………10 4、详细设计……………………………………………………………………………………10 4.1、服务器端设计(关键代码)………………………………………………………10 1、加载套接字库……………………………………………………………………10 2、创建并初始化套接字……………………………………………………………11 3、自定义消息即其响应函数(接收函数)的实现………………………………12 4.2、客户端设计(关键代码)…………………………………………………………15 1、加载套接字库……………………………………………………………………16 2、创建并初始化套接字……………………………………………………………16 3、自定义消息及响应函数实现……………………………………………………16 4、发送消息函数的实现……………………………………………………………17 5、消息记录的实现…………………………………………………………………18 5、使用说明(在 VMWare 虚拟机中测试) ……………………………………………………19 5.1、服务器端使用………………………………………………………………………19 5.2、客户端使用…………………………………………………………………………20 6、总结…………………………………………………………………………………………25 7、参考文献……………………………………………………………………………………25 - 2 -
1、引言 局域网(Local Area Network,LAN)是指在某一区域内由多台计算机互联成的计算机组。 一般是方圆几千米以内。局域网可以实现文件管理、应用软件共享、打印机共享、工作组内 的日程安排、电子邮件和传真通信服务等功能。局域网是封闭型的,可以由办公室内的两台 计算机组成,也可以由一个公司内的上千台计算机组成。由于局域网的应用广泛且有许多优 点,所以许多局域网软件业应运而生。本文将介绍如何开发一个基于 UDP 的局域网聊天室 软件。 1.1、本文的主要作用 本文主要工作是设计一个基于 WINDOWS 平台的局域网聊天室软件,然后阐述本软件的功 能、特点及使用方法,并详细阐述开发本软件所用的相关技术,具体分析本软件的功能及实 现方法,说明本软件的设计思想及方法。 1.2、开发平台与技术的选择及介绍 1.2.1、开发环境 本软件开发小组开发的聊天室软件是面向小型局域网的即时通信软件,例如中小型企业的内 网,一栋宿舍楼的局域网。对开发软件的要求如下:1、开发软件的机器必须稳定 2、开发 软件的操作系统必须选择恰当 3、软件必须尽可能适用于多版本操作系统(WINDOWS)4、 要求能运行该软件的机器配置尽可能低。 1.2.2、硬件环境 开发软件的机器应尽量采用高配置机器。开发本软件的机器配置为 CPU:CORE2 P8700,内 存:2GB 最低运行要求:处理器 Intel Pentium PIII 或更高处理器,内存 128M,局域网。 1.2.3、软件环境 本软件在 WINDOWS7 环境下开发,对于 WIN98 及以下操作系统不支持的 API 函数一律不 予采用。经测试本软件可以在 WIN2000 及以上操作系统中运行。本软件的开发平台为 VC++6.0,用基于对话框的 MFC 编写。 1.2.4、VC++6.0 简介 VC++是在 WINDOWS 平台下构建 32 位应用程序的强大而又复杂的开发工具,是目前世界 上使用最多的开发工具之一。VC++的应用非常广泛,从桌面应用程序到服务器端软件,从 系统软件到应用程序,从单机应用程序到分布式应用程序,从图形图像处理到游戏的开发, VC++无所不在。 1.2.5、Windows Sockets 网络应用程序的实现方式有多种方式,Windows Sockets 就是其中一种简单的实现方法。 Socket 是连接应用程序与网络驱动程序的桥梁,Socket 在应用程序中创建,通过绑定操作与 驱动程序建立关系。此后,应用程序送给 Socket 的数据,由 Socket 交给驱动程序向网络上 发送出去。计算机从网络上收到与该 Socket 绑定的 IP 地址和端口号相关的数据后,由驱动 程序交给 Socket,应用程序便可从该 Socket 中提取接收到的数据。网络应用程序就是这样 通过 Socket 进行数据的发送与接收。 2、相关开发技术的说明 2.1、Windows 程序内部运行机制简介 - 3 -
2.1.1、API 我们在编写标准 C 程序的时候,经常会调用各种库函数来辅助完成某些功能。在 C 程序中我 们使用最多的就是 printf 了,这些库函数是由你所使用的编译器厂商提供的。在 Windows 平台下,也有类似的函数可供调用;不同的是,这些函数是由 Windows 操作系统本身提供的。 Windows 操作系统提供了各种各样的函数,以便于我们开发 Windows 应用程序。这些函数是 Windows 操作系统提供给应用程序编程的接口(Application Programming Interface),简 称为 API 函数。我们在编写 Windows 程序时所说的 API 函数就是指系统提供的函数,所有主 要的 Windows 函数都在 Windows.h 头文件中进行了声明。 Windows 操作系统提供了 1000 多种 API 函数,作为开发人员,要记住这些 API 函数的调用 语法几乎不可能。其实微软提供的 API 函数大多数是有意义的单词的组合,每个单词的首字 母大写,例如 CreateWindow(创建窗口),ShowWindow(显示窗口),LoadIcon(加载图标), SendMessage(发送消息)等。这些函数的准确拼写与调用语法都可以在 MSDN 中查找到。 2.1.2、窗口与句柄 窗口是 Windows 应用程序中一个非常重要的元素,一个 Windows 应用程序至少要有一个窗口, 成为主窗口。窗口是屏幕上的一块矩形区域,是 Windows 应用程序与用户进行交互的接口。 利用窗口,可以接收用户的输入,以及显示输出。 WS_OVERLAPPEDWINDOW 类型窗口 在 Windows 应用程序中,窗口是通过窗口句柄(HWND)来标识的。我们要对某个窗口进行操 作,首先要得到这个窗口的句柄。句柄(HANDLE)是 Windows 应用程序中一个重要的概念, 使用也非常繁琐。在 Windows 程序中,有各种各样的资源的标识号,即句柄。在编程中我们 我们还会看到图标句柄(HICON)、光标句柄(HCURSOR)、和画刷句柄(HBRUSH)。 2.1.3、消息与消息队列 Windows 程序设计是一种完全不同于传统 DOS 方式的程序设计方法。它是一种事件驱动方式 的程序设计模式,主要是基于消息的。例如,当用户在窗口中绘图的时候,按下鼠标左键, 此时操作系统会感知到这一事件,于是将这个事件包装成一个消息,投递到应用程序的消息 队列中,然后应用程序从消息队列中取出消息并进行响应。在这个处理过程中,操作系统也 会给应用程序“发送消息”。所谓“发送消息”,实际上是操作系统调用程序中一个专门负责 处理消息的函数,这个函数称为窗口过程。 2.1.3.1、消息 - 4 -
在 Windows 程序中,消息是由 MSG 结构体来表示的。MSG 结构体的定义如下(参见 MSDN) typedef struct tagMSG { // msg HWND hwnd; UINT message; WPARAM wParam; LPARAM lParam; DWORD time; POINT pt; } MSG; hwnd Identifies the window whose window procedure receives the message. message Specifies the message number. wParam Specifies additional information about the message. The exact meaning depends on the value of the message member. lParam Specifies additional information about the message. The exact meaning depends on the value of the message member. time Specifies the time at which the message was posted. pt Specifies the cursor position, in screen coordinates, when the message was posted. 2.1.3.2、消息队列 每一个 Windows 应用程序开始执行后,系统都会为该程序创建一个消息队列,这个消息队列 用 来 存 放 该 程 序 创 建 的 窗 口 消 息 。 例 如 , 当 我 们 按 下 鼠 标 左 键 的 时 候 , 将 会 产 生 WM_LBUTTONDOWN 消息,系统将会将这个消息放到窗口所属的应用程序的消息队列中,等待 应用程序的处理。Windows 将产生的消息依次放到消息队列中,而应用程序则通过一个消息 循环不断地从消息队列中取出消息,并进行响应。 2.1.3.3、进队消息和不进队消息 Windows 程序中的消息可以分为“进队消息”和“不进队消息”。进队消息将由系统放到应 用程序的消息队列中,然后由应用程序取出并发送。不进队消息在系统调用窗口过程时直接 发给窗口。不管是进队消息还是不进队消息,最终都由系统调用窗口过程函数对消息进行处 理。 应用程序 输入输出设备 ③ ④ 消息队列 操作系统 ① ② - 5 -
2.2、套接字(socket)的引入 为了能够方便的开发网络应用软件,由美国伯克利大学在 UNIX 上推出了一种应用程序访问 通信协议的操作系统调用套接字(socket)。socket 的出现,使程序员可以方便地访问 TCP/IP,从而开发各种网络应用的程序。随着 UNIX 的应用推广,套接字在编写网络软件中 得到了极大地普及。后来,套接字又被引进了 Windows 等操作系统,成为开发网络应用程序 的非常有效快捷的工具。 套接字存在于通信区域中。通信区域也叫地址族,它是一个抽象的概念,主要用于将通过套 接字通信的进程的共有特性综合在一起。套接字通常只与一个区域的套接字交换数据(也有 可能跨区域通信,但这只在执行了某种转换进程后才能实现)。Windows Socket 只支持一个 区域通信:网际域(AF_INET),这个域被使用网际协议族通信的进程使用。 2.3、网络字节序 不同计算机存放多字节的顺序不同,有的机器在起始地址存放低位字节,有的机器在起始地 址存放高位字节。基于 Intel 的 CPU,即我们常用的 PC 机采用的时低位先存。为保证数据 的正确性,在网络协议中需要指定网络字节顺序,TCP/IP 协议使用 16 位整数和 32 位整数 的高位先存格式。由于不同的计算机存放数据字节的顺序不同,这样发送方发送数据后,即 使接收方收到数据,也有可能无法查看所接收到的数据。所以在网络中不同主机间进行通信 时,要统一采用网络字节序。 2.4、Windows Sockets 的实现 Windows Sockets 是 Microsoft Windows 的网络程序设计接口,它是从 Berkeley Sockets 扩展而来的,以动态链接库的形式提供给我们使用。Windows Sockets 在继承了 Berkeley Sockets 的主要特征的基础上,又对它进行了重要扩充。这些扩充是提供了一些异步函数, 并增加了符合 Windows 消息驱动特性的网络事件异步选择机制。 2.4.1、套接字的类型  流式套接字(SOCK_STREAM) 提供面向连接、可靠的数据传输服务,数据无差错、无重复的发送,并按发送顺序接收。流 式套接字实际上是基于 TCP 协议实现的。  数据报式套接字(SOCK_DGRAM) 提供面向无连接服务。数据包以独立包形式发送,不提供无错保证,数据可能丢失或重复, 并且接收顺序混乱。数据报式套接字实际上是基于 UDP 实现的。  原始套接字(SOCK_RAW) 2.4.2、基于 TCP(面向连接)的 socket 编程 本程序采用 UDP 的套接字编程,TCP 方式在此不作详细介绍。 2.4.3、基于 UDP(面向无连接)的 socket 编程 服务器端也叫接收端,对于基于 UDP(面向无连接)的套接字编程来说,它的服务器端和客 户端的概念不是很强化,我们也可以把服务器端,即先启动的一端称为接收端,发送数据的 一端称为发送端,也称为客户端。  接收端编写步骤: 1. 创建套接字(socket)。 2. 将套接字绑定到本地地址和端口上(bind)。 3. 等待接收数据(recvfrom)。 4. 关闭套接字。 - 6 -
对于基于 UDP 的套接字编程,虽然说是面向无连接的,但是为了完成这次通信,对于接收端 来说,它必须先启动以来接收客户端发送的数据,因此接收端必须告诉主机它在哪个地址和 端口上等待数据的到来,也就是说,接收端(服务器端)必须调用 bind 函数将套接字绑定 到一个本地地址和端口。  客户端的编写: 1. 创建套接字(socket) 2. 向服务器发送数据(sendto) 3. 关闭套接字 注意,在基于 UDP 的套接字编程时,利用的是 sendto 和 recvfrom 这两个函数实现数据的发 送与接收。 2.4.4、相关函数 2.4.4.1、WSAStartup 函数 在利用套接字编程时,第一步需要加载套接字库,这通过 WSAStartup 函数来实现。这个函 数有两个功能:一是加载套接字库,一是进行套接字库版本协商,这也是确定将使用的 socket 版本。 int WSAStartup(WORD wVersionRequested,LPWSADATA lpWSAData); 2.4.4.2、socket 函数 加载了套接字库后,就可以调用 socket 函数来创建套接字了。 SOCKET socket(int af,int type,int protocol ); 2.4.4.3、bind 函数 在创建套接字之后,应该将套接字绑定到本地的某个地址和端口上,这需要通过 bind 函数 来实现。 int bind(SOCKET s,const struct sockaddr FAR *name,intnamelen); 2.4.4.4、inet_addr 和 inet_ntoa 函数 可以将 IP 地址指定为 INADDR_ANY,允许套接字向任何分配给本机的 IP 地址发送或接收数 据。多数情况下,每个机器只有一个 IP 地址,但有的机器可能有多个网卡,每个网卡都可 以有自己的 IP 地址,用 INADDR_ANY 可以简化应用程序的编写。将地址指定为 INADDR_ANY, 将允许一个独立应用接受发自多个接口的回应。如果我们只想让套接字使用多个 IP 地址中 的一个地址,就必须指定实际地址,要做到这一点,可以用 inet_addr 函数来实现。 unsigned long inet_addr(const char FAR *cp ); 该函数可以将一个以十进制表示的 IP 地址字符串转换为 unsigned long 类型的数值。 inet_ntoa 函数会完成相反的转换,它接受一个 in_addr 结构体类型的参数并返回一个以点 分十进制格式表示的 IP 地址字符串。 char FAR * inet_ntoa(struct in_addr in ); 2.4.4.5、recvfrom 函数 Windows Sockets 的 recvfrom 函数将接收一个数据报的信息并保存源地址。 int recvfrom(SOCKET s,char FAR* buf,int len,int flags,struct sockaddr FAR *from,int FAR *fromlen); 2.4.4.6、sendto 函数 Windows Sockets 的 sendto 函数将向一个特定的目的方发送数据。 int sendto(SOCKET s,const char FAR *buf,int len,int flags,const struct sockaddr FAR *to,int tolen); 2.5、基于消息的异步套接字 - 7 -
Windows 套接字在两种模式下执行 I/O 操作:阻塞模式和非阻塞模式。在阻塞模式下,在 I/O 操作完成前,执行的 windows 函数会一直等待下去,不会立即返回,例如,在程序中调用 recvfrom 函数后,如果这时候网络上没有数据传送过来,该函数就会阻塞程序的执行,从 而导致调用线程暂停运行。解决该问题可以通过编写多线程程序。而在非阻塞模式下, Windows Sockets 函数无论如何都会立即返回,在该函数执行的操作完成之后,系统会采用 某种方式将操作结果通知给调用线程,后者可以通过通知信息判断该操作是否完成了。 因为在很多情况下,阻塞方式会影响到应用程序的性能,所以有时候需要采用非阻塞方式实 现网络应用程序,有多种机制可以实现这种方式。Windows Sockets 为了支持 Windows 消息 驱动机制,使应用程序开发者能够方便地处理网络通信,它对网络事件采用了基于消息的网 络事件选择,当使用它登记网络事件发生时,Windows 应用程序相应的窗口函数将收到一个 消息,消息中指示了发生的网络事件,以及与该事件相关的一些信息。 因此,可以针对不同的网络事件进行登记,例如,如果登记一个网络读取事件,一旦有数据 到来,就会触发这个事件,操作系统就会通过一个消息来通知调用线程,后者就可以在相应 的消息响应函数中接受这个数据。因为是在数据到来之后,操作系统发出通知,所以这时候 肯定能接受到数据。采用异步套接字能够有效地提高应用程序的性能。 2.5.1、相关函数 WSAAsyncSelect 函数 该函数为指定的套接字请求基于 Windows 消息的网络事件通知,并自动将该套接字设置为非 阻塞模式。 int WSAAsyncSelect(SOCKET s,HWND hWnd,unsigned int wMsg,long lEvent); 3、总体设计 3.1、工作流程 - 8 -
分享到:
收藏