基于TCP、UDP的聊天文件传输程序.docx

上传人:夺命阿水 文档编号:850231 上传时间:2023-12-27 格式:DOCX 页数:18 大小:211.70KB
返回 下载 相关 举报
基于TCP、UDP的聊天文件传输程序.docx_第1页
第1页 / 共18页
基于TCP、UDP的聊天文件传输程序.docx_第2页
第2页 / 共18页
基于TCP、UDP的聊天文件传输程序.docx_第3页
第3页 / 共18页
基于TCP、UDP的聊天文件传输程序.docx_第4页
第4页 / 共18页
基于TCP、UDP的聊天文件传输程序.docx_第5页
第5页 / 共18页
点击查看更多>>
资源描述

《基于TCP、UDP的聊天文件传输程序.docx》由会员分享,可在线阅读,更多相关《基于TCP、UDP的聊天文件传输程序.docx(18页珍藏版)》请在课桌文档上搜索。

1、网络通信原理课程题目基于TCP、UDP的聊天文件传输程序1111vf-目11 2yG*FJt12网络编程的预备知识12 .1TCP/IP协议族简介12.2用户数据报协议UDP22.3传输控制协议TCP33eJ!*.531.532QtNetWOrk63. 3整体结构和子模块划分74关键模块分析94. 1聊天内容传输模块4.2文件传输模块开发工具5.1 测试环境5.2 测试步骤实验总结6.1个人收获6.2待改善的问题参考资料1实验综述1.1 设计目标TCP/IP协议是Internet的基础和最基本的网络协议。本实验利用了UDP和TCP协议,实现一个具有聊天功能和文件传输功能的QT插件。实验中使用非

2、面向连接的UDP协议实现文字传输的功能,使用面向连接的TCP协议实现文件传输的功能。1.2 完成功能(1)布局界面,创建若干个按钮和输入控件和一个现实控件,如图1所示。(2)利用IJDPSOCKET实现网络聊天的功能。(3)利用Tcpsocket实现文件传输的功能。3TestWork.o!回一我的名字:图1程序界面2网络编程的预备知识2.1 TCP/IP协议族简介TCP/IP体系结构分为四层,分别是网络接口层、网际层、运输层和应用层。如图2所示的一种分层次画出具体协议的表示图可知,TCP/IP协议族具有“两头大而中间小”的特点。应用层和网络接口层都有多种协议,而中间的IP层是最小的,上层的各种

3、协议都向下汇聚到一个IP协议中。这种沙漏型的结构表明:TCP/IP协议可以为各式各样的应用提供服务(所谓的everthingoverIP)。同时TCP/IP协议也允许IP协议在各式各样的网络结构中构成互联网上运行(所谓的IPovereverything)0正因为如此,因特网才会发展到今天这种全球规模。从图2不难看出IP协议在因特网中起到核心的作用。我们应该知道的是,TCP/IP中的运输层向高层用户屏蔽了下层的网络核心细节(如网络拓扑、路由选择协议等),它使应用进程看见的就是好像在两个运输层实体之间有一条端到端的逻辑通信信道尽管下层可能存在着非常复杂的协议。图2TCP/IP协议族示意图运输层有两

4、个主要的协议,分别是面向连接的TCP协议和无连接的UDP协议。下面详细介绍这两个协议。2.2 用户数据报协议UDP用户数据报协议(USerDatagramProtocol,UDP)是一种无连接的网络协议,它只是在IP的数据报服务之上增加了很少的功能,即复用和解复用以及差错检测的功能。UDP的主要特点是:(1)UDP是无连接的,即发送数据之前不需要建立连接(当然发送数据结束之后也没有连接需要释放),因此减少了开销和发送数据之前的时延。(2) UDP使用尽最大努力交付,即不保证可靠交付,因此主机不需要维持复杂的连接状态表。(3) UDP是面向报文的。发送方的UDP对应用程序交下来的报文仅添加首部之

5、后就交付给IP层,也就是说,应用层交给UDP多长的报文,UDP照样发送。所以应用程序应该选择合适的报文大小,若报文过长,则IP层将会对UDP报文进行分片,降低了IP层的效率;反之,若报文太短,则导致IP首部相对过大,也降低了IP层的效率(4) UDP没有拥塞控制,因此网络出现拥塞不会对主机的发送速率造成影响。这对实时应用是很重要的。(5) UDP支持一对一、一对多、多对一和多对多的交互通信。(6) UDP首部仅有8个字节,开销较小。2.3传输控制协议TCP传输控制协议(TransmissionControlProtocol,TCP)是TCP/IP体系中非常复杂的一个协议,它具有如下特点:(I)

6、TCP是面向连接的运输层协议。这就是说,应用程序在使用TCP协议之前,必须先建立TCP连接。在传送数据结束之后,必须释放已建立的TCP连接。(2)每一条TCP连接只能有两个端点,每一条TCP连接只能是点对点的。(3) TCP提供可靠交付服务。也就是说,用户可以通过TCP协议无差错、不丢失、不重复且按序到达地传输数据。(4) TCP提供全双工通信。它允许连接的双方在任何时候发送数据。(5)面向字节流。TCP中的“流”指的是流入进程和从进程流出的字节序列。即应用程序与TCP的交互是一次一个数据块,但TCP把应用程序交下来的数据块仅看成一连串无结构的字节流。发送方应用进程字节流CE奉节写入 发送缓存

7、TCP /I】耳 ITIldI 目 I4加上TCP苜输、 构成TCP报文段IId 91Ha国表示TCP报文段的首部i, ? B表示序号为X的数据字节i图3TCP面向流的概念TCP对应用进程一次把多长的报文发到TCP的缓存器中并不关心,它会根据其发送窗口的大小来调整一个报文段有多长。如果发送来的数据太长,则它将对数据进行分段,如果太短,则会等待数据达到一定大小再发送。TCP所谓的面向连接并不是指真正的物理连接,而是一条建立在各种可靠性保隙机制上的序连接。连接是TCP最基本的抽象,TCP的很多特性都与其面向连接的这个基本特性有关。如前所述,每一条TCP连接有两个端点,这个端点不是主机,不是IP地址

8、、不是进程也不是运输层的端口,而是叫做套接字(SOCKET)O其定义是端口号拼接到点分十进制表示的IP地址上,用冒号或者逗号隔开。例如,有IP地址218.192.169.130而端口号是80,那么得到的套接字则为(218.192.169.130:80)。总之,我们有套接字SoCket=(IP地址:端口号)每一条TCP连接唯一地被通信两端的两个端点(即两个套接字)所确定。即:TCP连接:=socketl,socket2二(IP:portl),(IP,port2)总而言之,TCP连接就是由协议软件所提供的一种抽象。有时为了方便,我们也可以说,在一个应用进程和另一个应用进程之间建立了一条TCP连接,

9、但被连接的两端是套接字,同一个地址可以有多个不同的TCP连接,而同一个端口号也可以出现在多个不同的TCP连接中。TCP的可靠传输依靠于一系列复杂的机制,例如超时重传、拥塞控制等等,不作详述。3编程实现3.1 编程环境Qt是一个1991年由奇趣科技开发的跨平台C+图形用户界面应用程序开发框架。它既可以开发GUl程序,也可开发非GUl程序,比如控制台和服务器。Qt是面向对象语言,易于扩展,并且允许组件编程。基本上,Qt同XWindow上的Motif,Openwin,GTK等图形界面库和Windows平台上的MFC,OWL,VCL,ATL是同类型的东西。Qt与其他开发工具包最不相同的部分是它的“信号

10、和槽”(SignaIandslot)机制,这也是它的中心特征。图4信号和槽示意图在图形用户界面编程中,我们希望一个窗口部件的一个变化被通知给另外一个窗口部件。更一般地,我们希望任何一类的对象可以与其他对象进行通信。较老的工具包使用一种被称作回调的通讯方式来实现同一目的。回调是指一个函数指针,所以如果你希望一个处理函数通知你一些事件,你可以把另一个函数回调的指针传递给处理函数。处理函数在适当的时候调用回调。回调有两个主要的缺点。首先他们不是类型安全的。我们从不确定处理函数使用了正确的参数来调用回调。其次回调和处理函数是非常强地联系在一起的,因为处理函数必须知道要调用哪个回调。信号和槽机制是指,当

11、一个特定事件发生的时候,一个信号被发射。Qt的窗口部件有很多预定义的信号,但是我们总是可以通过继承来加入我们自己的信号。槽就是一个可以被调用处理特定信号的函数。Qt的窗口部件又很多预定义的槽,但是通常的习惯是你可以加入自己的槽,这样你就可以处理你所感兴趣的信号。信号和槽的机制是类型安全的:一个信号的签名必须与它的接收槽的签名相匹配。(实际上一个槽的签名可以比它接收的信号的签名少,因为它可以忽略额外的签名。)因为签名是一致的,编译器就可以帮助我们检测类型不匹配。信号和槽是宽松地联系在一起的:一个发射信号的类不用知道也不用注意哪个槽要接收这个信号。Qt的信号和槽的机制可以保证如果你把一个信号和一个

12、槽连接起来,槽会在正确的时间使用信号的参数而被调用。信号和槽可以使用任何数量、任何类型的参数。它们是完全类型安全的:不会再有回调核心转储(CoredUmp)。从QObject类或者它的一个子类(比如Qwidget类)继承的所有类可以包含信号和槽。当对象改变它们的状态的时候,信号被发送,从某种意义上讲,它们也许对外面的世界感兴趣。这就是所有的对象通讯时所做的一切。它不知道也不注意无论有没有东西接收它所发射的信号。这就是真正的信息封装,并且确保对象可以用作一个软件组件。3.2 QtNetworkQtNetwork是QT为用户提供网络功能的库,里面封装好许多个类为用户所用。本次试验用到的是QTcpS

13、erverQTcpSocket和QUdpSocket这三个类。QTcpServer提供一个TCP基础服务类,这个类用来接收到来的TCP连接,可以指定TCP端口或者用QTCPSerVer挑选一个端口,可以监听一个指定的地址或者所有的机器地址。用它的IiSten()函数监听所有连接,在有客户端连接到服务器端就会发射一个newConnection()信号,此时可以调用nextPendingConnection()来接受待处理的连接,并返回一个QTCPSOCket,我们可以用这个返回的套接字和客户端连接并通信。QTCPSoCket类提供一个套接字,可以用bind()函数绑定一个主机的端口,也可以用Co

14、nnectToHostO函数请求一个TCP连接。QUdPSOCket类可以用来发送和接收UDP数据报。采用UDP时,数据是以数据报的形式从一个主机发送到另一个主机的,此中没有连接的概念,如果UDP数据报没有成功发送,它并不会向发送者发送任何错误报告。3.3 整体结构和子模块划分/TestWorkTestWork.proih头文件MmyserverhIhIreceiverhh*senderhh*testwork.h.Cw源文件5main.cpp切myservercpp切receivercpp切sendecpp切testwork.cpp,J界面文件画receiveruisenderuitestwo

15、rk.ui图5整体结构图程序由主界面(TestWorkXTCP服务器类(MyServerX发送文件类(Sender)和接收文件类(Receiver)组成。MySerVer类派生自QTCPSerVer类,实质上是classTestWork:publicQWidgetQ_OBJECT图6主界面类的结构图public:explicit TestWork(QWidget parent 0);*estfor();QByteArray tep;QString host;private slots:void void void void void voidon_sendBtn_clicked();送机天内容

16、readUdpsocket();读取受到的UD嗜!据报on_FileBtn_clicked(); 发送文件transferFinish();transAbort();ResetBtnO ;文件发送完毕后显示信息文件传输中邃停止信息提示当发送结束旨 激活发送文件按钮private:Ui: STestWorJc *ui;MyServer wServer;QUdpSocket *MyUdpSocket;QString fileName;qint64 totalBytes;Sender sender;Receiver *receiver;/界面/QTcpServer /QUdpSocket存储待发送文

17、件的路径 待发送文件的大小 发送文件类融文件类目标地址:说骄么:聊天窗口:一个TCP服务器,程序启动时就会调用它建立一个服务器进行TCP连接的监听。当一个新的连接请求到来时,它将生成一个选项框(QMeSSageBOX)作传输控制,用户单击Yes后接收端才建立套接字传输数据,传输完成后双方都关闭套接字。等待下一次的连接。传输文件子模块可以理解为一个C/S结构的程序,客户端只有在向服务器提出文件传输的请求,服务器,即接收端才根据请求分配一个新的套接字进行传输任务,然而在程序运行的任何时刻,用户都可以使用聊天的功能,这由QUdPSOCket来完成。主界面类(TestWork)为整个程序提供一个交互界

18、面,完成所有交互功能,结构如图6所示。它包括了一些按钮和输入控件,一个用于显示聊天内容和一些信息提示的文本浏览器。除了提供界面外,该类还完成了聊天内容的收发。聊天是通过UDP数据包来实现的。classMyServer:publicQTcpServer(Q_0BJECTpublic:explicitMyServer(QObject*parent=0);voidStartServer();启动服务器,监听文件传输的工CP连接signals:publicslots:voidReceiverClosedO;/槽,用以姑理文件接收插件关闭时的事件protected:voidincomingconnect

19、ion(nzhandle);/该方法时新连接进行处理);图7服务器类(Myserver)结构图服务器类(Myserver)监听文件传输的请求,并且每当新连接到来时实例化一个接收文件类(Receiver),实现文件的传输。当用户点击发送按钮时,程序就会实例化一个Sender类,如图8所示,并向该类待传输文件的路径,然后发送文件。接收文件类(Receiver)与发送类十分相似,不作赘述。classSender:PUbliCQWidgetQ_OBJECTpublic:explicitSender(QStringHost,QStringFileName,QWidget*parenr=0);Sender

20、();privatesloes:voidUpdateClientProgress(qlnt64);发送数据并更新进度条voidStartTransferO;实现文件大小等信息的传输signals:voidtransferFnsh();/文件发送完成的信号private:U:Sender*u;界面QStringhost;/对方的主机IPQStringfIleName;/待发送文件的路径QTcpSocket*tcpClient;/QTcpSocJcetQFile*localFile;/要发送的文件qint64CotalBytes;/数据总大小qint64bytesWritten;/已经发送数据大小

21、qint64bytesToWrice;/剩余数据大小qinr64IoadSxze;每次发送数据的大小QByteArrayoutBlock;数据缓冲区,即存放每次要发送的数据);图8文件发送类(Sender)的结构图9文件传输流程图4关键模块分析4.1 聊天内容传输模块MyUdpSocket=newQUdpSocket(this);创建一个QUdPSoCketMyUdpSocket-bind(QllostAdclress:Any,1234);绑定端口connect(MyUdpSocket,SIGNAL(readyReadO),SLOT(readUdpsocket();连接数据到来的信号和读取数据

22、的槽voidTestWork:on_sendBtn_clicked()发送聊天内容的按钮响应(QByteArraydata;存储待发送的数据data,append(ui-NameEdit-text().toUtf8();获取发送者的昵称data,append(:r);data,append(ui-lineEdit-text().toUtf8()+n);获取对话内容QHostAddresshost;host=Ui-ipEdit-text();获得目标的IP地址MyUdpSocket-writeDatagram(data,host,1234);用QUdpSocket发送数据报ui-DialogWi

23、n-append(data);在本机的聊天窗口显示自己发送的内容)voidTestWork:IreadUdpsocketO读取UDP数据报的内容(QByteArraytoshow;存储接收回来的数据报toshow.resize(MyUdpSocket-pendingDatagramSize();使toshow和数据报大小相等MyUdpSocket-readDatagram(toshow.data(),toshow.size();读取数据报ui-DialogWin-append(toshow);/显示聊天内容)聊天功能仅涉及到两个QUdPSoCket的数据交换,发送端除了携带用户所说的话,还要携

24、带用户的名字,以便接收端的用户能知道发送者的身份,也有利于清晰地显示出对话的内容。由于UDP连接并没有建立连接,所以每个程序只要有一个QUdpSocket就可以实现跟其他任何用户通信。4.2 文件传输模块voidMyServer:IStartServer()(if(listen(QHostAddress:Any,8765)建立服务器,监听8765端口(qDebug()started”;else(qDebug()z,notstarted”;voidMyServer:incomingConnection(inthand1e)重写了原生的连接处理函数(qDebug(),zreceiverstarts

25、,setAttribute(Qt:WA_DcleteOnClose,true);传输完成时释放资源receiver-SetSocket(handle);receiver-show();客户端(发送端)voidTestWork:on_Fi1eBtn_c1ieked()发送文件按钮响应(fiIeName=QFileDialog:IgetOpenFileName(this);获得发送文件名if(!fileName.isEmpty()(ui-FileBtn-setEnabled(false);发送过程中不能再按发送ui-DialogWin-append(fileName);host=ui-ipEdit

26、-text();获得目标IP地址sender=newSender(host,fileName);实例化一个SCnder类connect(sender,SIGNAL(transferFinish(),this,SLOT(transferFinish();发送完成时作出提示connect(sender,SIGNAL(destroyed(),this,SLOT(ResetBtn();当sender类销毁后,重新激活发送文件按钮sender-setAttribute(Qt:WA_DeleteOnClose,true);sender-show();)Sender类建立之后,会创建一个QTcpSocket

27、来进行数据的传输。程序如下:tcpClient=newQTcpSocket(this);connect(tcpClient,SIGNAL(connected(),SLOT(startTransfer();连接建立后,开始传输数据connect(tcpClient,SIGNAL(disconnected(),this,SLOT(close();/QTcpSocket断开连接后,关闭这个Sender类connect(tcpClient,SIGNAL(bytesWritten(qint64),SLOT(UpdateClientProgress(qint64);每发送一段数据,更新发送进度条并且载入下

28、一次发送的数据块tcpClient-co77ctTbi5f(host,8765);向接收端发起连接文件传输开始时,会先传输待发送文件的基本信息:voidSenderiistartTransferO开始传输,先发送文件的大小等信息(qDebug()c5pe7(QFiIe:ReadOnly)qDebug()“openfileerror!”;return;)totalBytes=1ocalFi1e-size();文件总大小QDataStreamsendut(&outBlock,QIODevice:WriteOnljO;sendut.SetVersion(QDataStream:Qt_4_6);QSt

29、ringcurrentFi1eName=fiIeName.right(fiIeName.size()-fiIeName.IastIndexOf(,)-1);sendutqint64(0)qint64(0)currentFi1eName;依次写入总大小信息空间,文件名大小信息空间,文件名totalBytes+=outBlock.size();这里的总大小是文件名大小等信息和实际文件大小的总和sendut.device()-5eA(0);send0uttotalByteswrite(outBlock);发送完头数据后剩余数据的大小outBlock.resize(0);)bytesWritten变量

30、的变化用于调用更新进度条的程序段,也就是说,每当发送一个固定长度的数据,就会更新一次进度条,并且更新待发送的数据块。voidSender:UpdateClientProgress(qint64numBytes)不断更新进度条,实现文件的传送(bytesWritten+=(int)numBytes;己经发送数据的大小if(BytesToWrite0)如果已经发送了数据OUtBlock=IocalFile-read(qMin(bytesToWrite,IoadSize);每次发送IoadSizc大小的数据,这里设置为4KB,如果剩余的数据不足4KB,就发送剩余数据的大小BytesToWrite-=

31、(int)tcpClient-write(outBlock);发送完一次数据后还剩余数据的大小OUtBlock.resize(0);清空发送缓冲区else(IocalFile-c7ose();如果没有发送任何数据,则关闭文件ui-progressBar-setMaximum(totalBytes);ui-progressBar-setValue(BytesWritten);更新进度条if(bytesWritten=totalBytes)发送完毕(emittransferFinish();IocalFile-c7(7se();tcpClient-c7(75();this-deleteLater(

32、);5开发工具本实验所采用的开发工具为Qt5.0.205.1 测试环境(1)硬件环境:CPU双核2.2GHZ,内存2048MDDR3,网卡RELTEK8139EthernetAdapter,网络接入带宽100MHz局域网接入;(2)软件环境:使用系统为WindowS7o5.2 测试步骤(1)启动Qt,导入工程文件TeStWork.pro;点击BUiId构建项目,若信息框内出现错误提示,则根据错误提示进行改错,若无错误,则点击运行。(2)运行多两个程序,用本地环路127.0.0.1测试。(3)发送聊天数据,看聊天功能否正常,结果如图9。3TestWorkIO回区UTestWork我的名字:伸月目

33、标地址:127.001I传输文件照窗口:小东:你好我的名字:小东目标地址:IHOOi传输文件I聊天窗口:小东:说些什么:说些什么:WiI螳I图10聊天功能测试图(4)其中一方向另一方发送文件,测试文件传输功能,结果如图10、11。图11文件传输功能测试1 3 TestWorkI D 回 汉我的名字:小明说些什么: 雌 图12文件传输功能测试26实验总结6.1 个人收获通过本次大作业,我对TCP/IP协议的理解加深了。此外,本次是我的第一次网络编程,因此在这过程中学会了套接字的使用,最基本网络服务器的实现,也在编程过程中遇到了一些网络编程特有的问题。得益于Qt强大的功能和原来拥有的一些C+编程经

34、验,让本次编程的难度较使用MFC大为降低。本次所编的程序仅实现了简单的网络功能,但所使用的知识和方法均是网络编程的基础所在,再加上复杂的逻辑运算便可构成实用的网络应用程序。6.2 待改善的问题(1)操作不方便。在通信时,用户必须知道对方的IP地址并且只能一对一的操作,不贴近实际使用。将来可以建立一个有协调功能的主程序,把本实验的程序封装成一个可供调用的子类,并加入用户管理功能,使其功能更加实用。(2)资源管理不够好。在连续传输文件的过程中,偶尔会出现软件意外关闭的情况,这应该是资源冲突所造成的。这与本人的编程水平有关。此外,本软件所实现的全部功能都可以由Udpsocket全部完成,但是为了简化编程和体验UDP和TCP两种SOCKET的使用方法,用两种SOCKET分别来完成聊天和文件传输的功能。(3)消息提示机制不够完善。如果在文件传输的过程中使传输中断(发生意外事件或人工取消),接收端只是跟随终止了连接,并没有显示传输终止的原因,如果接收端用户没有留意的话很难知道接收是否成功。7参考资料1谢希仁.计算机网络(第5版).电子工业出版社.20082布兰切特等著;闫锋欣等译.C+GUIQt4编程(第2版).电子工业出版社.2008

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 在线阅读 > 生活休闲


备案号:宁ICP备20000045号-1

经营许可证:宁B2-20210002

宁公网安备 64010402000986号