基于socket的聊天程序设计.docx
- 文档编号:3510566
- 上传时间:2022-11-23
- 格式:DOCX
- 页数:35
- 大小:1.42MB
基于socket的聊天程序设计.docx
《基于socket的聊天程序设计.docx》由会员分享,可在线阅读,更多相关《基于socket的聊天程序设计.docx(35页珍藏版)》请在冰豆网上搜索。
基于socket的聊天程序设计
基于socket的聊天程序设计
摘要
无论是Windows还是Linux,网络通信的协议已经成为组成互联网的关键,硬件方面的路由交换协议:
rip,ospf,eigrp,bgp,isis,stp,rstp,vtp等,软件方面特别是传输层上的:
TCP/IP,UDP,应用层上的FTP,HTTP,TELNET,DNS,DHCP等。
这些都成了网络稳定通信的保证,但从某种意义上讲,网络本身是不稳定的,我们只是努力让其稳定。
即时通讯软件(IM),就是基于系统的消息交换机制,它在很大程度上方便了我们的交流,本系统是基于C/S模式,消息转发,语音,视频交互的简易局域网聊天工具,本身具有很强的扩展性,从98年到现在IM软件的发展是各个巨头的合作与统筹的结果。
本文是在线聊天室系统的开发说明,重点运用软件工程知识对系统进行分析、设计实现和测试的思想的具体描述,其中包括软件定义,软件开发和运行的维护这三个方面。
整个系统分为客户端和服务端两大端,客户端既可以实现局域网的文字聊天也可以实现点对点的语音和远程控制服务,目的是使软件的扩展性得到发挥,使软件满足广大客户的需求。
关键词:
IM,API,SOCKET,C/S,网络协议
Communication SoftwareDesign
Basedon WinSocket
Abstract:
EitherWindowsorLinux,networkcommunicationprotocolshasbecomeakeycomponentoftheInternet,hardware,routingexchangeprotocol:
rip,ospf,eigrp,bgp,isis,stp,rstp,vtp,etc.,softwareinparticularonthetransportlayer:
TCP/IP,UDP,applicationlayerFTP,HTTP,TELNET,DNS,DHCPandsoon. Thestabilityofcommunicationnetworkshavebecomeaguarantee,butfromsomesense,thenetworkitselfisunstable,wejusttrytomakethemstable.
Instantmessenger(IM),isbasedonthesystemmessageexchangemechanism,itislargelytofacilitateourcommunication,thesystemisbasedontheC/Smode,messageforwarding,voice,video,interactivesimpleLANchattoolitself highlyscalable,from98yearstothepresentdevelopmentofIMsoftwaregiantisalltheresultofcooperationandco-ordination.
Thisarticleis thedevelopmentof onlinechatroom that focuson usingsoftwareengineeringknowledge ofthesystem analysis,design, implementandtest thespecificdescriptionof theidea,including software-defined,softwaredevelopmentand maintenanceof thesethreeareas isrunning. Thewholesystem isdividedintotwomain :
clientand server,theclient caneither text chat inLAN and also pointtopointvoice andremote controlservice isintendedtoenable theexpansion of thesoftwareintofullplay, tomakethesoftware tocontentourcustomers Needs.
Keywords:
IM,API,SOCKET,C/S,networkprotocol
第一章VisualC++及Socket套接字介
1.1开发环境visualstudio2010
VS2010引入了多个新特性,整合了对象、关系型数据、XML的访问方式,语言更加简洁。
使用VisualStudio2010可以高效开发Windows应用。
设计中可以实时反映变更,XAML中智能感知功能可以提高开发效率。
同时微软也更新了他的sdk,使api更加的完善,比如本文后面使用的设置窗口透明度函数,这个在6.0中是不存在的,而vs2010增加了这个特性,并定义了这个API。
从vs的界面使用方面,对对象的分类和视图的属性更加强大,工具栏也人性话了。
对于代码的运行效果上看,查错能里得到了增强,比如printf这个函数会出发警告,因为此函数很有可能产生溢出。
在整体上,vs2010增加了使用效果,是整个系统更加稳定。
图1-1vs2010界面
1.2socket套接字基础
Winsock是一套开放的,支持多种协议的Windows下网络编程接口,是Windows网络编程实是上的标准.应用程序通过调用Winsock的API实现相互间的通信,而Winsock利用下层的网络通信协议功能和操作系统调用实现实际的通信工作。
1.2.1数据报文方式
套接字支持TCP/IP协议的网络通信的操作单元.可以将套接字看作不同主机间的进程进行双向通信的端点,它构成了单个主机内及整个网络间的编程界面.套接字存在于通信域中.通信域是为了处理一般的线程通过套接字通信而引进的一种抽象概念.套接字通过通常和同一个域中的套接字交换数据(数据交换也可能穿越域的界限,但这时一定要执行某种解释程序).Winsock规范支持单一的通信域,即Internet域.各种进程使用这个域互相之间用Internet协议簇来进行通信(Winsock1.1以上的版本支持其他的域)。
根据传输数据类型的不同,套按字可分为面向连接的数据套接字TCP和UDP两种类型:
●TCP字节流不按记录定界,在TCP/IP协议簇中对应TCP协议,即传输控制协议(TransmitionControlProtocol)。
它是一个提供给用户进程可靠的全双工的面向连接的协议,大多数INTERNET应用程序如ftp、telnet使用TCP协议。
通信端点使用TCP对应的INTERNET地址互相连接,可保证按正确的顺序以及单一和可靠的地址传输数据。
由于它是字节流,所以包长包没有限制,信包传输也不重复,因而是一种常用的套接字类型。
流套接字提供双向的,有序的,无重复并且无记录边界的数据流服务,它适应于处理大量数据.网络传输层可以将数据分散或集中到合适尺寸的数据包中。
流套接字是面向连接的,通信双方进行数据交换之前,必须建立一条路径,这样即确定了它们之间存在的路径,又保证了双方都是活动的,可彼此相应的,但在通信双方之间建立一个通信信道需要很多开支.除此以外,大部分面向连接的协议为保证发送无误,可能会需要执行额外的计算机来验证正确性,为此会进一步增加开支。
●数据报对应记录型数据流,在TCP/IP协议簇中对应UDP协议,即用户数据报协议(UserDatagramProtocol)。
利用数据报服务可实现一些简单的网络服务,如网点检测程序PING。
由于不建立连接,数据报协议比连接协议快。
但不能保证所有数据都准确有序地到达目的地。
不保证顺序性、可靠性和无重复性。
它是无连接的服务,以独立的信包进行传输,通信端点使用UDP对应的INTERNET地址。
双方不需互连,按固定的最大长度进行传输,因而适用于单个报文传输,或较小文件的传输。
数据报套接字支持双向的数据流,但不保证数据传输的可靠性,有序性,和无重复性.也就是说,一个从数据报套接字接受信息的进程有可能发现信息重复,或者和发出时间顺序不同的情况.此外,数据报套接字的一个重要特点是它保留了记录边界。
1.2.2套接字的编程要点及过程
图1-2套接字建立过程
1.3基本概念
1.3.1带外数据
带外数据,也称为TCP紧急数据,它是相连的每一对流套接字间的一个逻辑上独立的传输通道,带外数据是独立于普通数据传输给用户的,这一抽象要求带外数据设备必须支持每一时刻仅有一个带外数据信息等候发送。
对于仅支持带外数据的通信协议来说(例如紧急数据是与普通数据在同一序列发送),系统通常把紧急数据从普通数据中分离出来单独存放。
这就允许用户可以在顺序接受紧急数据和非顺序接收紧急数据之间作出选择。
1.3.2广播
数据报套接字可以用来向许多系统支持的网络发送广播数据包。
要实现这种功能,网络必须支持广播功能。
为此系统软件并不提供对广播功能的任何模拟。
广播信息将会给网络造成极重的负担,为此它们要求网络上的每台主机都为他们服务,所以发送广播数据包的能力被限制于那些用显式标记了允许广播的套接字中。
广播通常应用于以下两种情况:
一个应用程序希望在本地网络中找到一个资源。
而应用程序对该资源的地址又没有任何先验的知识。
一些重要功能,例如路由要求把它们的信息发送给所有可以找到的邻机。
1.3.3字节顺序
不同的计算机有时使用不同的字节顺序存储数据。
例如,基于Intel处理器的计算机和Macintosh计算机使用了相反的字节排序顺序。
Intel的字节顺序被成为“Little-Endian”,它与网络的字节排序顺序“Big-Endian”排序顺序相反。
任何从Winsock函数对IP地址和端口号的引用和传送给Winsock函数的IP地址和端口号均是按照网络顺序组织的,这也包括了sockaddr_in这一数据结构中的IP地址域和端口域
1.3.4阻塞和非阻塞
套接字可以处于阻塞模式或非阻塞模式。
调用任何一个阻塞模式地函数,都回产生相同地后果-耗费或长或短地时间等待操作地完成。
而当套接字处于非阻塞模式时,API函数的调用会立即返回,大多数情况这些调用都回“失败”,并返回一个WASEWOULDBLOCK的错误,它意味着请求的操作在调用期间没有时间完成。
Winsock的套接字I/O模型可以帮助应用程序判断一个套接字何时可供读写。
套接字的行为在Windows9X和WindowsNT中与在Windows3.1中不同.在32位操作系统中,可以采用多线程编程,在不同的线程中使用套接字,这样即使某个线程中的套接字被阻塞,也不会影响应用程序的其他操作,同时也不会在阻塞线程上耗费CPU时间。
1.3.5Winsock编程原理
客户机/服务器模型工作时要求有一套为客户机和服务器所共识的惯例来保证服务能够被提供(或被接受),这一套惯例包含了一套协议,它必须在通信的两头都被实现。
根据不同的实际情况,协议可能是对称的或非对称的。
在对称的协议中每一方都有可能扮演主从角色;在非对称协议中一方被不可改变地认为是主机,而另一方则是从机。
一个对称协议地例子是Internet中用于终端仿真地Telnet,而非对称协议地例子是Internet中的http。
无论具体的协议是对称的或是非对称的,当服务被提供时必然存在客户进程和服务进程。
一个服务程序通常在一个众所周知地地址监听客户对服务地请求,也就是说,服务进程一直处于休眠状态,直到一个客户对这个服务地址提出连接请求。
在这个时刻,服务程序被“惊醒”并且为客户提供服务-对客户地请求作出适当的反应。
1.3.6MFCWindowsSocket类
VsualC++对众多的socket函数进行了封装,MFC提供的封装类是:
CAsyncSocket和CSocket类。
●CAsyncSocket类所提供的唯一的抽象就是将与套接字相联系
Windows消息以回调函数的形式表示,因此它带来的唯一方便就是程序员无需自行处理Winsock的I/O模型,而对于如阻塞处理、字节顺序差异以及Unicode等依然负有责任并有灵活的控制权。
●CSocket类是CAsyncSocket类的派生类,它提供了对通过Carchive
对象使用套接字工作的更高级抽象。
CSocket类的使用比CAsynCSocket类更加容易,它继承了CAsyncSocket类的许多封装了API的成员函数,并且管理了通信的大多数方面,这使得用户从原来不得不使用原始API或者CAsyncSocket类的烦杂的工作中解脱出来。
更加重要的是CSocket和Carchive类提供了对于同步操作Carchive对象十分重要的阻塞功能,且CSocket通过与CSocketFile和Carchive一起使用来管理对象数据的发送和接收,使发送数据和操作变得简单明了。
第二章软件需求分析
需求分析在软件设计中扮演着决策者的角色,所以在所有设计中起着非常重要的作用。
根据网络应用程序的特点,网络在线聊天系统应就有即时,快速的特点。
服务器端和客户端应就有不同的功能特性。
对于服务器端应能够正确地建立与客户端的连接并能正确地断开,能即时地接收、处理和发送接收到的数据。
能及时地通知在线用户当前好友在线状况,能够处理非正常数据的能力。
对于客户端应能够快速地检查是否能够连接到服务器端。
能正确的获得和反映当前好友在线情况。
能够正确的与特定好友交流。
能及时地接收到服务器端地数据,并能即时处理数据,并能将处理结果反映给用户。
服务器端:
●能够正确地、无冲突地启动服务器。
●监听指定的端口,等待用户的连接。
●建立与客户端的逻辑连接,并能通知其他好友。
●向新进入的好友发出已上线的好友名单。
●接收客户端的消息请求,并能正确无误地处理消息,并能发出消息到客户端。
●反映当前在线人数和在线好友状况。
●及时地反映发出地消息和聊天消息。
●当好友断开与服务器端地连接时,服务器能够正确地断开连接,并通知其他用户。
●当用户违反聊天系统规定时,服务器系统管理员能够断开与此用户的连接。
●当服务器关闭时,应通知所有用户。
客户端:
●能够正确启动应用程序,并能向服务器发出连接请求。
●反映当前好友在线情况。
●能够向群体或指定好友发出消息
●能够及时接收好友发出消息,并通知用户。
●能够正确地断开与服务器端地的连接。
扩展模块:
●能够实现简单的语音端对端的对话功能。
●能够实现不要求画质简单的远程控制功能。
第三章功能描述
3.1服务器方案分析
图3-1服务端方案
服务端分析:
a.在特定端口上等待来自聊天客户端的连接请求,并且需要维护一个客户连接表,记录所有成功的连接。
b.即使接受从各个聊天客户发送过来的消息,然后把这些消息转发到另一个客户端的链接里。
c.监控这些连接的状态,在客户端离开时或发生故障时从表中删除对应的表项。
服务端的主要目的在于建立一个数据中转,完成客户端的各种需求,所以服务端的功能依据与客户端来建立,包括显示客户端的客户在线情况,客户端的消息等。
3.2客户端系统分析
图3-2客户端方案
客户端分析:
a.建立和维护与服务器的连接,并且随时监测连接的状态。
b.把用户输入的消息时时发送到服务器,另一客户端等待随时接受消息。
c.在用户端退出消息时关闭与服务器连接并告知。
经过这3个步骤,客户端即能完成简单的通信,在登录框中登录,登陆后在好友列表中显示,文本框的内容可以快速发送,如果有人退出,则在好友列表发出消息,这需要向服务器进行相应。
客户端的扩展部分分为语音和远程控制,服务器和客户端的建立完全依靠点对点的建立方式,为了和服务端产生冲突,在这两个扩展上使用了MFC的套接字建立方式,在远程控制中为了提高QOS,使用多线程的阻塞模式,这样数据可以连续传输,虽然阻塞模式有多种缺点,但采用多线程后会使视频质量更好,对于鼠标和键盘的模拟控制也更快,当然这也需要带宽的支持。
3.3可扩展端的分析
3.3.1语音聊天模块分析
图3-3-1语音模块分析
语音部分分析:
语音聊天实现起来很简单,但涉及到底层wave函数的开发,想要把数据进行压缩,实现高质量的通话就比较难了。
所以在写代码时避开了底层上的代码,只涉及简单的wave函数利用。
语音聊天的模块设计思路是发送声音的一端将硬件接口采集到得声音数据通过Socket发送到另一端,另外一端根据采集到得数据调用硬件接口的播放声音,其核心就是声音数据的采集,播放和数据网络的传输。
程序模块接口设计:
负责接收连接的服务器Socket模块,负责程序作为服务器的监听端口
负责接收、发送数据的客户端Socket,负责对Socket的数据进行消息处理
声卡的数据采集与播放:
采用相关波形的API,负责采集数据和播放声音数据
主框架的设计采用消息,参数和界面统一控制,负责整个程序的操作,负责用户的输入,声卡消息的处理
a.在建立好服务器和客户端后,首先进行音频初始化。
b.调用waveInOpen函数打开音频设备。
c.调用wavePrepareHeader函数开设录音缓冲区。
d.调用waveInAddBuffer函数实现录音。
(音频的捕捉和播放相反)
3.3.2远程控制模块分析
图3-3-2远控模块方案
远控端的分析:
远程监控的程序设计通过Socket和应用消息机制来监控客户端与被监控端得数据交换,从而达到监控与被监控的目的。
这样我们就需要2个独立的程序:
客户端Client和服务端Server。
服务端的模块设计:
网络模块负责监听客户端的connect,接收客户端发来的消息,包括键盘、鼠标等动作,本PC对这些消息进行处理,做出动作后发送到客户端。
编码、解码:
如果要对得到的图像进行处理,则需要对数据进行编码解码处理,本程序采用霍夫曼压缩。
主框架:
负责对Server端得消息窗口处理和映射。
客户端的设计:
网络部分:
负责监听服务端的Socket,对向服务端发来的数据进行处理,对发来的数据进行解压。
编码、解码:
对数据进行解压,多数采用霍夫曼来对数据进行解压。
主框架:
负责客户端窗口的消息机制处理。
第四章关键技术与算法
4.1服务端主体类
4.1.1主体服务端的函数
CServerDlg:
创建服务器主窗口,管理用户信息,用户在线状态等
CListenSocket:
用于监听客户端端口
CChatPacket:
数据包类
CCuserInfo:
用户信息类
CServerApp:
应用程序实例类
CArchive和CSocketFile为MFC类,与CClientSocket类一起实现数据的发送与接受。
这些类都是为启动服务端服务而创建的,其中启动服务中的InitInstance()函数定义了启动方式,用Creat方式创建了套接字和绑定了套接字,最后在Listen函数中监听。
如果在异步中创建套接字,则使用CAsyncSocket类。
当一切准备工作建立完成后,数据就应该被传送和接收,其中用到了OnReceive,OnSend,OnAccept,OnConnect,OnClose。
这样就完成了服务端的建立,并启动了监听。
4.1.2具体算法
在创建一个socket时,可以把他设置为阻塞,也可以设置为异步。
在缺省情况下,都创建为阻塞模式。
要使程序变成非阻塞,则可以使用WSAAsynSelect函数,这个函数的原型为:
intWSAAsyncSelect(SOCKETs,HWNDhWnd,u_intwMsg,longIEvent);其中参数1指定了要操作的socket句柄;参数2使用了窗口句柄,则最重要的是指定一个网络事件。
IEvent下的主要参数类型
FD_READ期望在套接字上收到数据(即读准备好)时接到通知
FD_WRITE期望在套接字上可发送数据(即写准备好)时接到通知
FD_OOB期望在套接字上有带外数据到达时接到通知
FD_ACCEPT期望在套接字上有外来连接时接到通知
FD_CONNECT期望在套接字连接建立完成时接到通知
FD_CLOSE期望在套接字关闭时接到通知
rc=WSAAsyncSelect(s,hWnd,wMsg,FD_READ|FD_WRITE);一般这样建立,就可以完成异步模式了。
如果想注销次次对话,则把事件置0就行了。
服务端创建完套接字后,剩下的就是绑定,监听,连接,关闭连接,关闭套接字。
如果采用了CREATE算法建立套接字,则采用另一种异步方式,也是建立套接字的主流方式,因为这种方式是面向流的套接字,使传输更加圆滑。
Create的函数原型为:
Create(UINTnSocketPort=0,
IntnSocketType=SOCK_STREAM,
LongIevent=FD_READ|FD_WRITE|FD_OOB|FD_ACCEPT|FD_CONNECT|FD_CLOSE,
LPCTSTRlpszSocketAddress=NULL);
这时Ievent已经有了整个通信的过程:
●FD_ACCEPT通知侦听套接字当前有连接请求可以接受OnAccept(intnErrorCode);
●FD_CONNECT通知请求连接的套接字,连接要求已被处理OnConnect(intnErrorCode);
●FD_CLOSE通知套接字与其连接的套接字已关闭OnClose(intnErrorCode);
●FD_READ通知有数据到达OnReceive(intnErrorCode);
●FD_WRITE通知可以发送数据OnSend(intnErrorCode);
●FD_OOB通知将有外带数据到达OnOutOfBandData(intErrorCode);
在MFC里建立套接字,其中有个著名的异步套接字类:
CAsyncSocket
与Winsock不同,CAsyncSocket服务端不用绑定(Bind),不用连接(Connect)。
正常情况下,服务器端必须首先创建一个CAsyncSocket套接字对象,并调用它的Create成员函数创建底层套接字句柄。
这个套接字对象专门用来侦听来自客户机的连接请求,所以称它为侦听套接字对象。
再调用侦听套接字对象的。
Listen函数,使侦听套接字对象开始侦听来自客户端的连接请求。
(1)当Listen函数确认并接纳了一个客户端连接请求后,触发FD_ACCEPT事件,侦听套接字收到通知,MFC框架自动调用侦听套接字的OnAccept事件处理函数。
一般需要重载OnAccept函数,再在其中调用侦听套接字对象的Accept函数。
(2)创建一个新的空套接字对象,专门用来与客户端连接并进行数据的传输,一般称为连接套接字,并作为参数传递给下一步的Accept成员函数。
m_sListenSocket.Accept(m_sConnectSocket);
在本次扩展端C/S模式中均采用这种方式来建立算法。
图4-1服务端算法
4.2客户端类
4.2.1主体客户端类
CClientDlg:
创建客户端主窗口
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 基于 socket 聊天 程序设计