使用Java实现数据报通信过程 Wayne
数据报(Datagram)使网络层数据单元在介质上传输信息的逻辑分组格式,
它是一种在互联网上传播的、独立的、包含地址信息的信息,能否到达目的地,
到达时间,内容是否会发生变化不能准确知道。它的通信双方都不需要建立联系
对于一些不需要高质量的应用程序来说,数据报告和通信是一个很好的选择。
Javajava在Java.在net包中,DatagramSocket和DatagramPacket有两种类型,用于应用程序
网络通信是通过报告通信的方式进行的。
下面,我想详细解释如何在Java中实现客户端和服务器之间的数据报告和通信。请看
:
一、客户端应用程序的工作流程
1) 首先,通过创建DatagramSocket对象,我们可以建立数据报告通信的Socket。
在Java中,DatagramSocket类有以下两种结构方法:
a)public DatagramSocket() 构建数据报告socket,并与本地主机任一起使用
端口连接。如果不能打开socket,则抛出socketexception异常。
b) public DatagramSocket(int port) 构建数据报告socket,并与当地主机指定
端口连接。如果socket或socket无法连接到指定的端口,则抛出socketexception
常。
2) 为实现无连接的包传输服务,创建数据报文包。每个数据报文包都是用来做的
创建DatagramPacket类,DatagramPacket对象包装数据报包数据、包长度、目标地点
地址,目标端口。作为客户端,需要发送数据报文包,以下形式调用DatagramPacket类
构建函数创建DatagramPacket对象,将要发送的数据和包文目的地址信息放入对象中
。
DatagramPacket(byte bufferedarray[],int length,InetAddress address,int port)即构造
一个长度为length的包发送到指定主机指定端口号的数据报文包。参数length必须
小于等于bufferedary.length
Datagrampacket提供了四个类别来获取信息
a) public byte[] getData() 返回字节数组,包括收到或发送的数据报告中的数据
b) public int getLength() 返回发送或接收到的数据的长度
c) public InetAddress getAddress() 返回发送或接收此数据报包文本的机器IP地点
址
d) public int getPort() 返回发送或接收数据报告的远程主机的端口号。
3)创建DatagramSocket和DatagramPacket对象后,即可发送数据报文包。发送
发送是通过调用Datagramsocket对象的send来实现的,它需要以Datagrampacket对象为参考对象
数字,发布刚刚包装在DatagramPacket对象中的数据组成数据。
4)当然,为了接收从服务器返回的结果,我们也可以接收数据报文包
,我们需要创建一个新的DatagramPacket对象,这就需要另一个DatagramPacket对象。
DatagramPackete(byte bufferedarray[],int length),也就是说,只需指示存储接收的数量
报告的缓冲区和长度。调用Datagramsocket对象的receive()方法完成接收数据报告的工作
此时,需要将上述创建的DatagramPacket对象作为参数,该方法将永远阻止知道收到
此时,DatagramPacket的缓冲区包含接收到的数据和数据报文包
该包还包含发送者的IP地址、发送者机器上的端口号等信息。
5)处理接收缓冲区数据,获取服务结果。
6)通信完成后,可以使用Datagramsocket对象的close()方法关闭数据并报告通信
Socket。当然,Java会自动关闭Socket,释放DatagramSocket和DatagramPacket所占的
使用的资源。然而,作为一种良好的编程习惯,它仍然需要显示并关闭。接下来,我给出一个简单的客户端程序,使用数据报告和通信,它可以完成与服务器的简单通信
新闻。为了直观,我把它写成了Applet程序,因为这篇文章没有介绍Applet,所以我只写了一篇简短的文章
要注释,对Applet感兴趣的朋友亲自参考相关书籍。
import java.applet.*; import java.awt.*; import java.net.*; import java.io.*;
public final class javaCommunicationClient extends Applet { private Label label1,label2 ; private Panel panel1,panel2; private TextField textfield; private TextArea textarea; private DatagramSocket sendSocket,receiveSocket;///声明发送数据报告Socket和接收
Socket数据报告 private DatagramPacket sendPacket,receivePacket;///声明发送数据报文包和接收数据
据报文包
public void init() { setBackground(Color.gray); setLayout(new BorderLayout());///设置布局管理器 panel1=new Panel(); panel1.setLayout(new BorderLayout());///将布局管理器放置在容器中 label1=new Label(“通话记录”); textarea=new TextArea(10,20);///文本显示区域 textarea.setText(欢迎您!"); panel1.add("North",label1);///在布局管理器中添加标签 panel1.add("Center",textarea); add("North",panel1); label2=new Label(“说话:”;//创建另一个容器 panel2.add("Center",label2); textfield=new TextField(20); textfield.setText(""); panel2.add("South",textfield); add("Center",panel2); show(); }
public void start() { waitForPackets(); }
public void waitForPackets()
/*方法waitforpacket用于监控服务器的数据报告。获得数据报告后,文本显示
显示区域
*/ { try { sendSocket=new DatagramSocket();///实例化发送数据报告Socket对象 receiveSocket= new DatagramSocket(5001);//实例化一个接收数据报告Socket对象
,以5001为端口
} catch (SocketException e)//捕获异常 { textarea.appendText(”数据报Socket无法打开,或者数据报Socket无法与指定端口相匹配
连接!"); } while (true) { try { byte buf[]=new byte[100]; receivePacket=new DatagramPacket(buf,buf.length);///实例化一个接收数据
报文包对象
receiveSocket.receive(receivePacket);//以receivePacket为参数,接受文包 textarea.appendText(\t"); byte[] data=receivePacket.getData(); String receivedString=new String(data); textarea.appendText(receivedString);///显示接收到的数据报文中的数据
出来 } catch(IOException e) { textarea.appendText(“网络通信错误,问题在”+e.toString()); } } }
public boolean action(Event e,Object o) { try {textarea.appendText(\n客户端:; String string=o.toString(); textarea.appendText(string); byte[] databyte=new byte[100]; string.getBytes(0,string.length(),databyte,0); sendPacket=new
DatagramPacket(databyte,string.length(),InetAddress.getByName5000(202.38.64.4);//发
发送数据报告,您可以在自己的主机IP替换器中使用IP地址 sendSocket.send(sendPacket); }catch(IOException ioe) { textarea.appendText(”网络通信出现错误,问题在"+ioe.toString()); } return true; }
}
二、服务器端应用程序的工作流程
与基于数据流通信的方式不同,通信双方不应在数据报告通信中建立连接,
因此,服务器应用程序的通信过程与客户端应用程序的通信过程非常相似,也需要建立
立数据报告通信DatagramSocket,构建数据报文包DatagramPacket,接收数据报告并发送数据
据报道,接收缓冲区的处理内部数据,通信完成后,关闭数据报告通信Socket。不同的是,
服务器应用程序应该面向网络中的所有计算机,因此服务器应用程序应该在收到包后
分析它,获取数据报告的源地址信息,从而为客户机创建正确的返回结果报告。
由于服务器端的相应应用程序和服务器端的服务器段程序,我给出了一个数据报告和通信服务器段程序
客户端程序相似,不想详细注释,只列出程序供大家参考:
1、javaCommunicationServer.java
import java.net.*; import java.io.*; import java.awt.*; import java.applet.Applet;
public final class javaCommunicationServer extends Frame { private Label label1,label2 ; private Panel panel1,panel2; private TextField textfield; private String name,name1; private TextArea textarea; private DatagramSocket sendSocket,receiveSocket; private DatagramPacket sendPacket,receivePacket;
public javaChatServer() { super(通信控制台:;//使用超级结构方法,构建Frame panel1=new Panel(); panel1.setLayout(new BorderLayout()); label1=new Label(“通话记录”); textarea=new TextArea(10,20); textarea.setText(欢迎您!");
panel1.add("North",label1); panel1.add("Center",textarea); add("North",panel1); panel2=new Panel(); panel2.setLayout(new BorderLayout()); label2=new Label(“说话:”; panel2.add("Center",label2); textfield=new TextField(20); panel2.add("South",textfield); add("Center",panel2); show();
try { sendSocket=new DatagramSocket(); receiveSocket= new DatagramSocket(5000); } catch (SocketException e) { e.printStackTrace(); System.exit(1); } }
public void waitForPacket() { while (true) { try { byte buf[]=new byte[100]; receivePacket=new DatagramPacket(buf,buf.length); receiveSocket.receive(receivePacket); name=receivePacket.getAddress().toString(); if(name1!=name) { textarea.appendText“\n来自主机:”+name+"\n端口:
"+receivePacket.getPort()); } textarea.appendText(\n客户:t"); byte[] data=receivePacket.getData(); String receivedString=new String(data,0); textarea.appendText(receivedString); name1=name; }
catch(IOException e) { textarea.appendText(“网络通信错误,问题在”+e.toString()); } } }
public boolean handleEvent(Event e) { if(e.id==Event.WINDOWS_DESTROY) { hide(); dispose(); System.exit(0); } return super.handleEvent(e); }
public boolean action(Event e,Object o) { try {textarea.appendText(\n服务器:; String string=o.toString(); textarea.appendText(string); byte[] databyte=new byte[100]; string.getBytes(0,string.length(),databyte,0); sendPacket=new
DatagramPacket(databyte,string.length(),InetAddress.getByName(name),5001); sendSocket.send(sendPacket); }catch(IOException ioe) { textarea.appendText(”网络通信出现错误,问题在"+ioe.toString()); } return true; }
}
2、CommunicationServerRun.java,建立javacomunicationserver的实例,然后运行
。
import javaCommunicationServer class CommunicationServerRun extends javaCommunicationServer { public static void main(String args[]) { javaCommunicationServer cs=new javaCommunicationServer(); cs.waitForPacket(); } }