当前位置: 代码迷 >> 综合 >> java基础复习-多线程UDP
  详细解决方案

java基础复习-多线程UDP

热度:55   发布时间:2023-09-23 11:55:35.0

      java使用DatagramSocket代表UDP协议的Socket,DatagramSocket本身只是码头,不维护状态,不能产生IO流,它的唯一作用就是接收和发送数据报,Java使用DatagramPacket来代表数据报,DatagramSocket接收和发送的数据都是通过DatagramPacket对象完成的。

DatagramSocket构造函数说明:


DatagramSocket():创建实例。通常用于客户端编程,它并没有特定监听的端口,仅仅使用一个临时的。 
DatagramSocket(int port):创建实例,并固定监听Port端口的报文。 
DatagramSocket(int port, InetAddress localAddr):这是个非常有用的构建器,当一台机器拥有多于一个IP地址的时候,由它创建的实例仅仅接收来自LocalAddr的报文


方法说明:

receive(DatagramPacket p):从该DatagramSocket中接收数据报。

send(DatagramPacket p):以该DatagramSocket对象向外发送数据报。

setSoTimeout(int timeout):设置超时时间,单位为毫秒。 
close():关闭DatagramSocket。在应用程序退出的时候,通常会主动释放资源,关闭Socket,但是由于异常地退出可能造成资源无法回收。所以,应该在程序完成时,主动使用此方法关闭Socket,或在捕获到异常抛出后关闭Sock
注意:1.在创建DatagramSocket类实例时,如果端口已经被使用,会产生一个SocketException的异常抛出,并导致程序非法终止,这个异常应该注意捕获。

DatagramPacket 构造函数说明:

DatagramPacket(byte[] buf, int length, InetAddress addr, int port):从buf数组中,取出length长的数据创建数据包对象,目标是addr地址,port端口。 
DatagramPacket(byte[] buf, int offset, int length, InetAddress address, int port):从buf数组中,取出offset开始的、length长的数据创建数据包对象,目标是addr地址,port端口。 
DatagramPacket(byte[] buf, int offset, int length):将数据包中从offset开始、length长的数据装进buf数组。
DatagramPacket(byte[] buf, int length):将数据包中length长的数据装进buf数组。

方法说明:

getData():它从实例中取得报文的byte数组编码。



创建发送线程


package thread;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;public class SendThread implements Runnable {private DatagramSocket ds;public SendThread(DatagramSocket ds) {this.ds = ds;}@Overridepublic void run() {try {// 封装键盘录入数据BufferedReader br = new BufferedReader(new InputStreamReader(System.in));String line = null;while ((line = br.readLine()) != null) {if ("886".equals(line)) {System.exit(0);//输入886终止发送}// 创建数据并打包byte[] bys = line.getBytes();// DatagramPacket dp = new DatagramPacket(bys, bys.length,// InetAddress.getByName("192.168.12.92"), 12345);DatagramPacket dp = new DatagramPacket(bys, bys.length,InetAddress.getByName("127.0.0.1"), 12306);System.out.println("正在发送数据。。。");// 发送数据ds.send(dp);System.out.println("发送 成功!");}// 释放资源ds.close();} catch (IOException e) {e.printStackTrace();}}}

创建接收线程

package thread;import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;public class ReceiveThread implements Runnable {private DatagramSocket ds;//创建接收和发送UDP的Socket实例public ReceiveThread(DatagramSocket ds) {this.ds = ds;}@Overridepublic void run() {try {while (true) {// 创建一个包裹byte[] bys = new byte[1024];DatagramPacket dp = new DatagramPacket(bys, bys.length);System.out.println("正在接收到数据。。。");// 接收数据ds.receive(dp);System.out.println("接收成功!");// 解析数据String ip = dp.getAddress().getHostAddress();String s = new String(dp.getData(), 0, dp.getLength());System.out.println("from " + ip + " data is : " + s);}} catch (IOException e) {e.printStackTrace();}}}

主线程

package thread;import java.io.IOException;
import java.net.DatagramSocket;/** 实现在一个窗口发送和接收数据*/
public class ChatRoom {public static void main(String[] args) throws IOException {DatagramSocket dsSend = new DatagramSocket();DatagramSocket dsReceive = new DatagramSocket(12306);SendThread st = new SendThread(dsSend);ReceiveThread rt = new ReceiveThread(dsReceive);Thread t1 = new Thread(st);Thread t2 = new Thread(rt);t1.start();t2.start();}
}
      1.DatagramPacket与DatagramSocket位于Java.NET包中

  2..DatagramPacket表示存放数据的数据报,DatagramSocket表示接受或发送数据报的套接字

  3..由这两个类所有构成的网络链接是基于UDP协议,是一种不可靠的协议。

  之所以不可靠是因为发送方不负责数据是否发送成功,接收方收到数据时也不会向发送方反馈成功消息,容易导致信息的丢失。