当前位置:文档之家› 计算机网络课程设计利用java实现UDP协议

计算机网络课程设计利用java实现UDP协议

Ƽѧѧ뼼רҵ计算机网络课程设计利用java 实现UDP协议系别计算机与通信工程学院专业计算机科学与技术学号4110415姓名张振指导教师王聪2014年7月4日1.需求分析程序是如何通过网络进行相互通信的呢?各个孤立的工作站或主机用物理链路相连在一起,组成数据链路,从而达到资源共享和通信的目的,就形成网络。

通信是人与人之间同过某种媒体进行的信息交流与传递。

网络通信一般指网络协议。

当今网络协议有很多,其中基本最常用的就是TCP/IP 协议族。

UDP 协议就是属于TCP/IP协议族中的协议。

在网络中它与TCP协议一样用于处理数据包。

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

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

本文利用Java语言网络编程的思想,编写UDP协议程序,实现UDP协议在网络中所要完成的功能。

在Java语言为实现程序的相互通信提供了许多有用的抽象应用程序接口(API, Application Programming Interface),这类应用程序接口被称为套接字(sockets)。

因此,本文UDP协议的编程所需要用到的接口就是套接字。

2.实验环境开发环境: 个人PC+win8.1+myeclipse 103.实验原理以及相关内容3.1 UDP简介UDP 是User Datagram Protocol的简称,中文全称是用户数据包协议,是一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务。

在网络中它与TCP协议一样用于处理数据包。

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

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

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

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

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

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

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

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

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

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

(6)UDP是面向报文的。

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

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

3.3 UDP套接字UDP协议提供了一种不同于TCP协议的端到端服务。

实际上UDP协议只实现两个功能:(1).在IP协议的基础上添加了另一层地址(端口);(2).对数据传输过程中可能产生的数据错误进行了检测,并抛弃已经损坏的数据。

由于其简单性,UDP套接字具有一些与我们之前所看到的TCP套接字不同的特征。

例如,UDP套接字在使用前不需要进行连接。

TCP协议与电话通信相似,而UDP协议则与邮件通信相似:你寄包裹或信件时不需要进行“连接”,但是你得为每个包裹和信件指定目的地址。

类似的,每条信息(即数据报文,datagram)负载了自己的地址信息,并与其他信息相互独立。

在接收信息时,UDP套接字扮演的角色就像是一个信箱,从不同地址发送来的信件和包裹都可以放到里面。

一旦被创建,UDP套接字就可以用来连续地向不同的地址发送信息,或从任何地址接收信息。

UDP套接字与TCP套接字的另一个不同点在于他们对信息边界的处理方式不同:UDP 套接字将保留边界信息。

这个特性使应用程序在接受信息时,从某些方面来说比使用TCP 套接字更简单。

最后一个不同点是,UDP协议所提供的端到端传输服务是尽力而为(best-effort)的,即UDP套接字将尽可能地传送信息,但并不保证信息一定能成功到达目的地址,而且信息到达的顺序与其发送顺序不一定一致(就像通过邮政部门寄信一样)。

因此,使用了UDP套接字的程序必须准备好处理信息的丢失和重排。

4.实验内容4.1 流程图UDP应用程序原理图UDP 应用程序流程图 DatagramSocket SSocket = new DatagramSocket (ServerPort );SSocket.receive(Spacket);DatagramPacket Spacket = new DatagramPacket (buf,buf.length);CSocket.receive(Cpacket);DatagramPacket Cpacket = new DatagramPacket (buf,buf.length,address,ServerPort);DatagramSocket CSocket = new DatagramSocket ();CSocket.send(Cpacket);SSocket.send(Sendpacket);CSocket.close();CSocket.close();DatagramPacket Sendpacket = new DatagramPacket (buf,buf.length,address,ClientPort );DatagramPacket Rec_packet = new DatagramPacket (buf,buf.length);4.2 实例解析3.3.1 UDP 服务器端UDP 服务器要执行以下三步:(1).创建一个DatagramSocket 实例,指定本地端口号,并可以选择指定本地地址。

此时,服务器已经准备好从任何客户端接收数据报文。

(2).使用DatagramSocket类的receive()方法老接收一个DatagramPacket实例。

当receive() 方法返回时,数据报文就包含了客户端的地址与端口,这样我们就知道回复信息该发送到什么地方。

(3).使用DatagramSocket类的send()和receive()方法发送和接收DatagramPacket实例,进行通信。

//服务器类UDPServerBean.javapackage UDP;import java.io.*;import .*;public class UDPServerBean {private DatagramSocket dSocket;private int ClientPort;private int ServerPort;private InetAddress ServerIP;private InetAddress ClientIP;private String content;// 无参构造函数public UDPServerBean() throws SocketException,UnknownHostException {ClientPort = 1111;ServerPort = 1001;content = "";ClientIP = InetAddress.getLocalHost();ServerIP = InetAddress.getLocalHost();dSocket = new DatagramSocket(ServerPort);}// 信息发送函数,将接收到的信息发回给用户public void sendToClient() throws IOException{byte[] Buffer = ("服务器已经收到:\n "+content).getBytes();// 将要发送的信息给Buffer变量DatagramPacket dPacket = newDatagramPacket(Buffer,Buffer.length,getClientIP(),getClientPort());//创建DatagramPacket对象dPacket,并设置客户机的IP地址与端口号dSocket.send(dPacket); //发送信息}// 以下全是UDPServerBean类的各个成员变量的get和set方法public InetAddress getServerIP() {return ServerIP;}public void setServerIP(InetAddress serverIP) throws Exception {ServerIP = serverIP;}public DatagramSocket getdSocket() {return dSocket;}public void setdSocket(DatagramSocket dSocket) {this.dSocket = dSocket;}public int getClientPort() {return ClientPort;}public void setClientPort(int clientPort) {ClientPort = clientPort;}public int getServerPort() {return ServerPort;}public void setServerPort(int serverPort) throws SocketException { ServerPort = serverPort;}public String getContent() {return content;}public void setContent(String content) {this.content = content;}public InetAddress getClientIP() {return ClientIP;}public void setClientrIP(InetAddress clientIP) {ClientIP = clientIP;}}//服务器端代码,UDPServer.javapackage UDP;import java.awt.*;import java.awt.event.*;import java.io.*;import .*;import javax.swing.*;public class UDPServer extends JApplet{private UDPServerBean server;private Thread thread;private JTextField jtf_ServerPort = new JTextField(10);private JButton jbt_Strat = new JButton("启动");private JButton jbt_Exit= new JButton("退出");private JTextArea jta_Server = new JTextArea();public UDPServer() {JPanel jplServer11 = new JPanel();jplServer11.add(new JLabel("服务器端口:"));jplServer11.add(jtf_ServerPort);JPanel jplServer21= new JPanel();jplServer21.add(jbt_Strat);jplServer21.add(jbt_Exit);JPanel jplServer0= new JPanel();jplServer0.setLayout(new GridLayout(2,1));jplServer0.add(jplServer11,BorderLayout.NORTH);jplServer0.add(jplServer21);add(jplServer0,BorderLayout.NORTH);add(new JScrollPane(jta_Server),BorderLayout.CENTER);// 使用线程thread = new Thread(new Runnable(){public void run() {receiveForemClient(); //调用发送函数}});//启动按钮事件jbt_Strat.addActionListener(new ActionListener(){public void actionPerformed(ActionEvent e) {int serPort = Integer.parseInt(jtf_ServerPort.getText()); // 从jtf_ServerPort文本区中取服务器的端口号try {server = new UDPServerBean(); //创建服务器UDPServerBean的类对象server.setServerPort(serPort); //将取得的服务器端口serPort给server对象jta_Server.setText("设置服务器端口为"+jtf_ServerPort.getText()+" ,服务器开启...\n"); // 将服务器端设置好的信息显示在jta_Server文本域中thread.start(); //启动线程} catch (SocketException e2) {e2.printStackTrace();}catch (UnknownHostException e1) {e1.printStackTrace();} catch (Exception e1) {e1.printStackTrace();}}});// 退出按钮的触发事件jbt_Exit.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {System.exit(0);}});}// 接收客户端的信息,并将接收到的信息发回给客户机public void receiveForemClient(){String rec_str = null;byte[] Buffer = new byte [1024];try {server.setdSocket(newDatagramSocket(server.getServerPort(),server.getServerIP())); // server对象调用setdSocket()函数,创建新Socket对象(此时服务器端口号为设定的端口号)} catch (SocketException e) {e.printStackTrace();}DatagramPacket dPacket = newDatagramPacket(Buffer,Buffer.length); //创建DatagramPacket对象dPacketwhile(true){ // 用循环监听信息接收try {server.getdSocket().receive(dPacket); //接受信息,将接收到的信息存放在dPacket对象中rec_str = newString(dPacket.getData(),0,dPacket.getLength()); //取出dPacket对象中接收到的信息server.setClientPort(dPacket.getPort()); // 将dPacket对象中包含的客户机的端口号给server对象server.setClientrIP(dPacket.getAddress()); // 将dPacket对象中包含的客户机的IP给server对象server.setContent(rec_str); // 将接收的信息给server对象jta_Server.setText(jta_Server.getText()+"收到IP地址为"+server.getClientIP()+",端口为 "+server.getClientPort()+" 的客户机的信息有:\n "+rec_str+"\n"); // 将客户机的信息与接收的信息显示在jta_Server文本域中server.sendToClient(); //将信息发送回去} catch (IOException e) {e.printStackTrace();}}}}UDP客户端UDP客户端首先向被动等待联系的服务器端发送一个数据报文。

相关主题