基于UDP的即时通信工具的设计开发.docx

上传人:b****7 文档编号:15481992 上传时间:2023-07-04 格式:DOCX 页数:37 大小:496.18KB
下载 相关 举报
基于UDP的即时通信工具的设计开发.docx_第1页
第1页 / 共37页
基于UDP的即时通信工具的设计开发.docx_第2页
第2页 / 共37页
基于UDP的即时通信工具的设计开发.docx_第3页
第3页 / 共37页
基于UDP的即时通信工具的设计开发.docx_第4页
第4页 / 共37页
基于UDP的即时通信工具的设计开发.docx_第5页
第5页 / 共37页
基于UDP的即时通信工具的设计开发.docx_第6页
第6页 / 共37页
基于UDP的即时通信工具的设计开发.docx_第7页
第7页 / 共37页
基于UDP的即时通信工具的设计开发.docx_第8页
第8页 / 共37页
基于UDP的即时通信工具的设计开发.docx_第9页
第9页 / 共37页
基于UDP的即时通信工具的设计开发.docx_第10页
第10页 / 共37页
基于UDP的即时通信工具的设计开发.docx_第11页
第11页 / 共37页
基于UDP的即时通信工具的设计开发.docx_第12页
第12页 / 共37页
基于UDP的即时通信工具的设计开发.docx_第13页
第13页 / 共37页
基于UDP的即时通信工具的设计开发.docx_第14页
第14页 / 共37页
基于UDP的即时通信工具的设计开发.docx_第15页
第15页 / 共37页
基于UDP的即时通信工具的设计开发.docx_第16页
第16页 / 共37页
基于UDP的即时通信工具的设计开发.docx_第17页
第17页 / 共37页
基于UDP的即时通信工具的设计开发.docx_第18页
第18页 / 共37页
基于UDP的即时通信工具的设计开发.docx_第19页
第19页 / 共37页
基于UDP的即时通信工具的设计开发.docx_第20页
第20页 / 共37页
亲,该文档总共37页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

基于UDP的即时通信工具的设计开发.docx

《基于UDP的即时通信工具的设计开发.docx》由会员分享,可在线阅读,更多相关《基于UDP的即时通信工具的设计开发.docx(37页珍藏版)》请在冰点文库上搜索。

基于UDP的即时通信工具的设计开发.docx

基于UDP的即时通信工具的设计开发

 

计算机网络课程设计报告

基于UDP的即时通信工具的设计开发

 

 

江苏大学计算机学院

 

2015年7月2日

目录

1设计要求与开发环境4

1.1目标与内容4

1.2要求5

1.3实现要求5

2UDP协议5

2.1UDP协议简介5

2.2UDP的使用6

2.3UDP的特性7

3程序设计8

3.1点对点通信8

3.1.1设计思路8

3.1.2具体实现8

3.2群组即时通信9

3.2.1设计思路9

3.2.2服务器11

1用户类和在线用户11

2流程图12

3具体实现13

4界面设计13

5实现的功能14

3.2.3客户端14

1本地用户类14

2具体实现14

3界面设计15

4项目测试15

5过程与总结17

1设计要求与开发环境

1.1目标与内容

(1)任务一,设计一个基于UDP的点对点通信工具,实现点对点的通信,如下图所示,用户发送的信息将在对方用户中显示,显示内容包括“源IP+发送时间+发送内容”。

(2)任务二,设计实现一个基于UDP的群组即时通信工具,如下图所示,每个用户发送的信息将在其他用户中显示,显示内容包括“用户名+发送时间+发送内容”。

其中功能主要包括:

用户注册、用户登录、用户删除、信息发送与接收、信息保存、历史信息查询等

1.2要求

(1)熟悉C#.NET开发环境

(2)熟悉Socket等相关通信组件

(3)通信协议的定义、封装与解析

(4)也可以采用自己熟悉的开发语言或工具实现

1.3实现要求

1基于UDP的点对点通信工具,实现点对点的通信,用户发送的信息将在对方用户中显示,显示内容包括“源IP+发送时间+发送内容”。

2实现一个基于UDP的群组即时通信工具,每个用户发送的信息将在其他用户中显示,显示内容包括“用户名+发送时间+发送内容”。

3对于2中还要实现功能主要包括:

用户注册、用户登录、用户删除、信息发送与接收、信息保存、历史信息查询等。

1.4开发环境

软件环境:

MicrosoftVisualStudio2008使用C#编写

硬件环境:

计算机学院305电脑,个人笔记本电脑

2UDP协议

2.1UDP协议简介

UDP是UserDatagramProtocol的简称,中文名是用户数据报协议,是OSI(OpenSystemInterconnection,开放式系统互联)参考模型中一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务,IETFRFC768是UDP的正式规范。

UDP在IP报文的协议号是17。

UDP协议全称是用户数据报协议,在网络中它与TCP协议一样用于处理数据包,是一种无连接的协议。

在OSI模型中,在第四层——传输层,处于IP协议的上一层。

UDP有不提供数据包分组、组装和不能对数据包进行排序的缺点,也就是说,当报文发送之后,是无法得知其是否安全完整到达的。

UDP用来支持那些需要在计算机之间传输数据的网络应用。

包括网络视频会议系统在内的众多的客户/服务器模式的网络应用都需要使用UDP协议。

UDP协议从问世至今已经被使用了很多年,虽然其最初的光彩已经被一些类似协议所掩盖,但是即使是在今天UDP仍然不失为一项非常实用和可行的网络传输层协议。

2.2UDP的使用

在选择使用协议的时候,选择UDP必须要谨慎。

在网络质量令人十分不满意的环境下,UDP协议数据包丢失会比较严重。

但是由于UDP的特性:

它不属于连接型协议,因而具有资源消耗小,处理速度快的优点,所以通常音频、视频和普通数据在传送时使用UDP较多,因为它们即使偶尔丢失一两个数据包,也不会对接收结果产生太大影响。

比如我们聊天用的QQ就是使用的UDP协议。

虽然UDP是一个不可靠的协议,但它是分发信息的一个理想协议。

2.3UDP的特性

(1)UDP是一个无连接协议,传输数据之前发送端和接收端不建立连接,当UDP它想传送时就简单地去抓取来自应用程序的数据,并尽可能快地把它扔到网络上。

在发送端,UDP传送数据的速度仅仅是受应用程序生成数据的速度、计算机的能力和传输带宽的限制;在接收端,UDP把每个消息段放在队列中,应用程序每次从队列中读一个消息段。

(2)由于传输数据不建立连接,因此也就不需要维护连接状态,包括收发状态等,因此一台服务机可同时向多个客户机传输相同的消息。

(3)UDP信息包的标题很短,只有8个字节,相对于TCP的20个字节信息包的额外开销很小。

(4)吞吐量不受拥挤控制算法的调节,只受应用软件生成数据的速率、传输带宽、源端和终端主机性能的限制。

(5)UDP使用尽最大努力交付,即不保证可靠交付,因此主机不需要维持复杂的链接状态表(这里面有许多参数)。

(6)UDP是面向报文的。

发送方的UDP对应用程序交下来的报文,在添加首部后就向下交付给IP层。

既不拆分,也不合并,而是保留这些报文的边界,因此,应用程序需要选择合适的报文大小。

(以上内容摘录自XX百科)

3程序设计

3.1点对点通信

3.1.1设计思路

程序开始运行时启动一个接收线程,接收线程中将启用一个固定端口号如8000专门用于接收数据并且处于后台运行状态,也就是说程序启动到结束程序的这一过程中程序一直在监听是否有信息发送到该程序,若接收到数据,则将数据处理后显示在消息窗口;当发送用户要发送消息时,发送用户先输入接收用户的用户信息,程序会接受用户输入的用于发送的内容,经处理后通过UDP协议将用户数据发送出去同时将其显示本地的消息窗口。

3.1.2具体实现

1接收线程

程序开始运行时接收函数启动开始接收线程并一直在后台运行监听消息,调用的listen()函数中有用于接收的无限循环。

privatevoidReceive()//接收函数

{

thread=newThread(newThreadStart(listen));//新建进程

thread.IsBackground=true;//设置为后台进程

thread.Start();//线程开始

}

2发送函数

按下发送按钮后,程序将自动获取用户输入的目的IP、端口号、要发送的内容最后发送。

privatevoidbtSend_Click(objectsender,EventArgse)//发送

{

stringdstIP=this.IpAddress.Text.ToString();//获取目的IP

stringdstPort=this.PortNo.Text.ToString();//获取目的端口stringtemp=this.SendMessage.Text;//获取要发送消息

byte[]sendData=System.Text.Encoding.UTF8.GetBytes(temp);//将发送的字符串转换为byte[]

//将IP地址字符串转化为IP地址和端口号实例

udpSender.Connect(IPAddress.Parse(dstIP),Int32.Parse(dstPort));//发送用户开始连接接收用户udpSender.Send(sendData,sendData.Length);//向接收用户发送消息

stringdataTime=System.DateTime.Now.ToString();//获取系统时间

Message.Items.Add("本机:

");//将发送的消息在本地输出

Message.Items.Add(dataTime);

Message.Items.Add(temp);

SendMessage.Clear();//清空输入框

}

3界面设计

3.2群组即时通信

3.2.1设计思路

群组即时通信是要实现当群组内的一个用户发送消息时其他在线的每个用户要能收到这一消息。

参考点对点通信,我们可以这样想,在点对点通信中,发送用户只是对要接收的单个用户发送了消息,现在让群组通信中的客户端即发送用户来实现这一功能只是接收的用户不在是一个而是两个或多个。

但这样做在实现发送时会变得十分复杂,较难解决该发给谁这个问题。

因为这时对在线用户即接收用户的处理是分散在每个客户端独立地进行,客服端重复工作且较易出错,给客户端带来不必要的负担。

因此引入了服务器,由服务器进行这个将消息转发给所有在线用户的过程。

客户端只需将要发送的数据发送给服务器就可以了,剩下的工作全部交给服务器处理,服务器将会把每个客户端发送过来的有效数据转发给每个在线用户。

当然,服务器同样面临着将消息发给谁的问题。

解决好这个问题才有可能做到余下要求的功能。

在点对点的通信中,通信的原理是发送方依据接收方的IP地址和端口号组成的IPEndPoint的内容类似于收信人地址来把消息正确送达接收方的。

所以在服务器端关于发给谁的这个问题就是把每个要接收的客户端的用于接收的IPEndPoint保存起来组成一个在线用户列表,在发送的时候把它调用出来依据这个在线用户列表对要发送的消息给每个要接收的客户端转发一遍。

这样就解决了发给谁这个核心问题。

这样服务器将负责在线用户列表的更新和维护,提高效率和正确性的同时也节约了资源。

此时,客户端对在线用户的获取只需将服务器处理过后的在线用户列表发送给客户端,客户端接收带有用户列表的数据处理后再将其输出到屏幕。

余下的功能就可以依靠这个转发的功能来实现。

首先,在服务器创建一个空的用户列表和一个空的在线用户列表。

以后当有用户注册时就将其用户信息如用户名、用户密码、在线状态等写入一个空的用户并保存起来。

有用户上线就将该用户发送过来的用来接收的IPEndPoint写入这个用户的用户信息中代替原有的无效的内容,同时把这个用户加入到在线用户列表。

用户下线时只需修改用户的在线状态和在线用户列表即可。

总的设计思路大概就是这样,在服务器建一个用于接收的用户列表,以这个列表的用户内容为依据来转发消息。

编写过程中要注意的是服务器和客户端之间的沟通交流,数据在服务器和客户端间传送,双方都应能理解。

所以先写服务器再根据服务器的设定来编写客户端。

3.2.2服务器

服务器的功能较多而且需要用到很多的判断语句。

1用户类和在线用户

用户类要包含用户的基本信息用户名和用户密码、用户用于接收的IPEndPoint,为了便于用户在用户列表和在线用户列表间的处理在用户类中还增添了一个整型数据用于表示用户在在线用户列表中的位置。

在线用户列表是一个用于保存在线用户在用户列表中的数组下标的整型数组。

用户列表的容量可以适当扩充,在线用户列表的容量则需根据服务器的处理能力来设置。

publicclassuser

{

publicstringuserName;//用户名

publicstringuserKey;//用户密码

publicIPEndPointuserRecIPEndPoint;//用户接收IPendPoint

publicboolstatus;//用户状态,true在线、false下线

publicintposition;//在用户列表中的位置

}

user[]userlist=newuser[1000];//创建1000个空用户

int[]nowUserPosition=newint[100];//记录在线用户位置在用户列表的位置即在线用户列表

2流程图

服务器一启动就一直处于接收数据状态,接收到数据后依据数据的不同转入对相应数据的处理。

处理完回到接收数据状态。

3具体实现

listen()为主要函数,该函数负责数据的接收和接收对数据的处理,对数据的处理通过调用相应的函数来处理。

如登录用户发来的数据中含有登录数据其组成为登录指令+接收端口+用户名+用户密码,各数据段用字符#区隔,登录指令为login,服务器一接收到login#开头的数据就调用登录函数。

对收到数据的判别和处理在源代码中将有详细说明,这里不再赘述。

privateintsearchclient(stringuserName)//查询userName用户是否在用户列表

privateboolclientLogin(stringreceiveData,IPAddressdstIP)//登录函数处理用户登录和添加

privateboolclientleave(stringuserName)//用户下线函数

privatevoidshow()//显示当前服务器信息和在线用户并更新用户列表

privatevoidsend(stringsendData,intnoRec)//对除noRec在线用户进行群发

privatevoidlisten()//监听函数

privatevoidReceive()//启动接收线程

privatevoidbtnSaveMesssage_Click(objectsender,EventArgse)//保存消息日志

privatevoidbtnDelete_Click(objectsender,EventArgse)//删除指定用户

4界面设计

5实现的功能

用户的登录、注册、验证;在服务端对用户的删除,指定路径保存消息记录;消息的群发,将在线用户列表发送到在线用户。

基于核心的转发功能和用户列表服务器经过适当的改进还可以添加更多的功能。

3.2.3客户端

客户端和点对点的通信对比就是多了对服务器信息的识别和处理还有用户登录、注册,结构上很相近。

1本地用户类

本地用户的内容只需简单的用户名和密码还有用于接收的端口号。

classuser//本地用户类

{

publicstaticstringuserName;//用户名

publicstaticstringuserKey;//用户密码

publicstaticintmyRecPort;//本地接收端口号

}

2具体实现

开始会进入login()进入登录窗口停留等待并发送用户信息直到收到服务器登录成功的消息,在进入聊天界面。

privateboollogin()//登录函数

privatevoidsend(stringtemp)//向服务器发送数据temp

privatevoidbtnSend_Click(objectsender,EventArgse)//点击发送按钮发送输入的内容

privatevoidlisten()//监听函数

privatevoidReceive()//启动接收线程

privatevoidbtnSave_Click(objectsender,EventArgse)//保存当前消息框的内容

3界面设计

4项目测试

测试结果实现了客户端间的群聊,服务器对用户的删除以及对聊天信息的保存。

下图是使用点对点通信对服务器进行测试接收到的数据符合预期。

余下的图为使用服务器和客户端进行测试的截图。

客户端用户hhh

客户端用户ggg

服务器

5过程与总结

这是一次编程的新体验。

读大学两年了没有做出过什么东西,之前大一时虽然有专门的编程课但实际上机和做课程设计的时候总是会感到力不能及很容易遇到错误而且感觉自己无论如何做也解决不了,最后不了了之。

这次课程设计虽然是使用从未接触过的C#来编写。

开始的时候也遇到了很大的困难,比如对窗体的熟悉过程中,由于之前没有这方面的经验导致即使借了几本书来参考,也没有头绪,尤其是要基于UDP更是不知道怎么办。

之后从网上看了部分教学视频开始渐渐找到感觉。

试做成功了一个简单的窗口程序。

发现C#在某种层次上比C++简单得多。

当然后面遇到的困难解决起来比这复杂。

每当遇到实在解决不了的问题时,就算卡住半天也不能在放弃了,因为放弃就做不到接下来要实现的功能。

有些问题在网上不停的查找和参考最终可能还解决不了,要感谢同学的帮助。

第一次写服务器的时候我是基于IP地址来标识用户的,不久就实现了群聊,但是要在不同的电脑才能实现,因为每台电脑在同一个网络中只有一个IP而且每个客户端都使用8000端口接收服务器的消息。

接着又依着第一次大致结构重新写了服务器,把用户标识更改为字符,同时创建了用户类把接收用户的地址改为可变的,在这一过程中最难的是用户类的使用,在创建了用户数组后每次运行到更改用户信息的时候就出错。

最后在网页上的一个小角落发现在使用数组前还要实例化,使用for循环全部实例化后终于没有这个问题。

总之遇到的问题有很多,程序上还有需要完善的地方。

最后我想说这次课程设计激起了我对编程的兴趣,毕竟实现了在两台电脑间通信还有群聊。

学习和使用了一种新的编程语言。

还有这次时间比较仓促对运行错误处理得不好。

我觉得平时个人时间是比较充裕的,可是在课程设计短短的时间内对于基础一般的人要确实自己去完成程序达到课程设计的要求实在比较困难,希望老师能考虑这些情况把课程设计的部分内容当作平时练习来布置,适当延长课程设计的周期让大家有机会在平时多锻炼锻炼,就是早点课设。

感谢老师。

附源代码

服务器用户类

usingSystem;

usingSystem.Collections.Generic;

usingSystem.Linq;

usingSystem.Text;

usingSystem.Net;

usingSystem.Net.Sockets;

namespaceUDPSever

{

publicclassuser

{

publicstringuserName;//用户名

publicstringuserKey;//用户密码

publicIPEndPointuserRecIPEndPoint;//用户接收IPendPoint

publicboolstatus;//用户状态,true在线、false下线

publicintposition;//在用户列表中的位置

}

}

窗口一

usingSystem;

usingSystem.Collections.Generic;

usingSystem.ComponentModel;

usingSystem.Data;

usingSystem.Drawing;

usingSystem.Linq;

usingSystem.Text;

usingSystem.Windows.Forms;

usingSystem.Net;

usingSystem.Net.Sockets;

usingSystem.Threading;

usingSystem.Timers;

usingSystem.IO;

namespaceUDPSever

{

publicpartialclassForm1:

Form

{

publicForm1()

{

CheckForIllegalCrossThreadCalls=false;

InitializeComponent();

show();

for(inti=0;i<1000;i++)//将userlist[1000]实例化

userlist[i]=newuser();

Receive();

}

userrefuseUser=newuser();//拒绝登录用户

user[]userlist=newuser[1000];//创建1000个空用户

int[]nowUserPosition=newint[100];//记录在线用户位置在用户列表的位置即在线用户列表

IPEndPoint[]clientesIPEndPoint=newIPEndPoint[100];//保存用户IP//IPEndPoint[]clientsIPEndPoint=newIPEndPoint[100];//保存用户接收端口

intuserNumber=-1;//+1表示用户数量用作用户数组下标

intnowUserNumber=-1;//+1表示在线用户数

constintrecPort=8888;//监听端口号

UdpClientudpReceiver=newUdpClient(recPort);//接收的UDP对象

UdpClientudpSender=newUdpClient();//发送的UDP对象

ThreadreceiveThread;//发送线程

privateintsearchclient(stringuserName)//查询userName用户是否在用户列表

{

for(inti=0;i<=userNumber;i++)

{

if(userlist[i].userName==userName)//存在用户userName返回其位置

returni;

}

return-1;//不存在返回-1

}

privateboolclientLogin(stringreceiveData,IPAddressdstIP)//登录函数处理用户登录和添加

{

string[]userInformation=receiveData.Split('#');//登录数据划分,登录字段组成:

登录指令+接收端口+用户名+用户密码

inti=searchclient(userInformation[2]);//检查登录用户是否在用户列表中

Int32dstPort=Int32.Parse(userInformation[1]);

if(nowUserNumber==99||userNumber==999)//超出服务器处理能力

{

refuseUser.userRecIPEndPoint=newIPEndPoint(dstIP,dstPort);

byte[]sendRefuseBytes=System.Text.Encoding.UTF8.GetBytes("refuse");

udpSender.Send(sendRefuseBytes,sendRefuseBytes.Length);//通知请求登录用户登录失败

MessageBox.Show("服务器处理能力受限,无法加入新用户");//提示服务器处理能力受限

returnfalse;

}

if(i==-1)//不在用户列表中添加新用户

{

userlist[++userNumber].userName=userInformation[2];//添加用户名

userlist[userNumber].userKey=userInformation[3].ToString();//添加用户密码

userlist[userNumber].userRecIPEndPoint=newIPEndPoint(dstIP,dstPort);//更改用户接收IPEndPoint

userlist[userNumber].status=true;//更改为在线状态

nowUserPosition[++nowUserNumber]=userNumb

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

当前位置:首页 > 小学教育 > 语文

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2