【橘猫笔记】UDP网络编程 Java简单实现全双工通信

UDP基础

DatagramSocket:用于发送或接收数据报包 服务器端的DatagramSocket将DatagramPacket发送到网络上,
然后被客户端的DatagramSocket接收。
send(DatagramPacket p) :从此套接字发送数据报包
receive(DatagramPacket p) :从此套接字接收数据报包
close() :关闭此数据报套接字

DatagramPacket:数据容器(封包)的作用 数据报包用来实现封数据报包的功能
getData() :获取发送或接收的数据

简单分析

启动两个线程,分别监听端口上是否有数据包,和通过本机通信端口发送数据报。
A端和B端都需要两个线程,IP和端口分别设置好就行。
接收
主要使用DatagramSocket数据包套接字的receive()方法接收数据包;DatagramPacketgetPort()获得包信息里面的远程端口,getData()获得包中的字节数组信息,getLength()获得字节数组长度。
发送
使用DatagramPacket的构造方法 DatagramPacket(byte[] buf, int length, SocketAddress address)制作好数据包,调用DatagramSocket数据包套接字的send()方法通过本地端口发送至对端端口。

客户端A端

package com.ujiuye.udp_thread;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.SocketException;
import java.util.Scanner;
/*
	DatagramSocket:用于发送或接收数据报包
	服务器端的DatagramSocket将DatagramPacket发送到网络上,然后被客户端的DatagramSocket接收。
	send(DatagramPacket p) :从此套接字发送数据报包
	receive(DatagramPacket p) :从此套接字接收数据报包
	close() :关闭此数据报套接字

	DatagramPacket:数据容器(封包)的作用
	数据报包用来实现封数据报包的功能
	getData() :获取发送或接收的数据
*/

/**
 * 
 * @author <a href="https://blog.csdn.net/qq_35341203">可乐橘猫</a>
 * @Date 2019年05月11日
 * @version 1.0
 */
public class ClientA {
	public static void main(String[] args) {
		DatagramSocket ds;
		try {
			ds = new DatagramSocket(33333);//创建数据报套接字并将其绑定到本地主机上的指定端口33333
			System.out.println("本机A端口:"+ds.getLocalPort());
			ReadA ra = new ReadA(ds);
			ra.start();//创建接收信息线程,并启动
			SendA sa = new SendA(ds);
			sa.start();//创建发送信息线程,并启动
		} catch (SocketException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
}

/**
 * a端接收类 
 * 定义port:33333
 */
class ReadA extends Thread {
	byte[] by = new byte[1024];
	DatagramSocket ds;
	DatagramPacket dp;

	public ReadA(DatagramSocket ds) {
		this.ds = ds;
	}

	@Override
	public void run() {
		while (true) {
			dp = new DatagramPacket(by, by.length);
			try {
				//接收B端发送的数据报
				ds.receive(dp);// 阻塞方法
				//接收的数据包转成字符串形式输出
				String str = new String(dp.getData(), 0, dp.getLength());
				System.out.println("端口:"+dp.getPort()+"->"+str);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}

/**
 * a端发送类 定义port:33333
 */

class SendA extends Thread {
	Scanner sc = new Scanner(System.in);
	byte[] by;
	DatagramPacket dp;
	DatagramSocket ds;
	public SendA(DatagramSocket ds) {
		this.ds = ds;
	}

	@Override
	public void run() {
		while (true) {
			String str = sc.next();
			by = str.getBytes();
			//获取键盘录入字符数组,告知数据包发送给指定端口 地址 和数组长度
			dp = new DatagramPacket(by, by.length, new InetSocketAddress(
					"localhost", 33334));
			try {
				ds.send(dp);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

}

客户端B端

package com.ujiuye.udp_thread;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.SocketException;
import java.util.Scanner;

/*DatagramSocket:用于发送或接收数据报包
服务器端的DatagramSocket将DatagramPacket发送到网络上,然后被客户端的DatagramSocket接收。
send(DatagramPacket p) :从此套接字发送数据报包
receive(DatagramPacket p) :从此套接字接收数据报包
close() :关闭此数据报套接字
DatagramPacket:数据容器(封包)的作用
数据报包用来实现封数据报包的功能
getData() :获取发送或接收的数据*/

/**
 * 
 * @author <a href="https://blog.csdn.net/qq_35341203">可乐橘猫</a>
 * @Date 2019年05月11日
 * @version 1.0
 */
public class ClientB {
	public static void main(String[] args) {
		
		DatagramSocket ds;
		try {
			ds = new DatagramSocket(33334);//创建数据报套接字并将其绑定到本地主机上的指定端口33334
			System.out.println("本机B端口:"+ds.getLocalPort());
			ReadB ra = new ReadB(ds);
			ra.start();
			SendB sa = new SendB(ds);
			sa.start();
		} catch (SocketException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

/**
 * B端接收类 
 * 定义port:33334
 */
class ReadB extends Thread {
	byte[] by = new byte[1024];
	DatagramSocket ds;
	DatagramPacket dp;

	public ReadB(DatagramSocket ds) {
		this.ds = ds;
	}

	@Override
	public void run() {
		while (true) {
			dp = new DatagramPacket(by, by.length);
			try {
				//接收A端发送的数据报
				ds.receive(dp);// 阻塞方法
				//接收的数据包转成字符串形式输出
				String str = new String(dp.getData(), 0, dp.getLength());
				System.out.println("端口:"+dp.getPort()+"->"+str);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
}
/**
 * B端发送类
 * 定义port:33334
 */
class SendB extends Thread {
	Scanner sc = new Scanner(System.in);
	byte[] by;
	DatagramPacket dp;
	DatagramSocket ds;

	public SendB(DatagramSocket ds) {
		this.ds = ds;
	}

	@Override
	public void run() {
		while (true) {
			String str = sc.next();
			by = str.getBytes();
			//获取键盘录入字符数组,告知数据包发送给指定端口 地址 和数组长度
			dp = new DatagramPacket(by, by.length, new InetSocketAddress(
					"localhost", 33333));
			try {
				ds.send(dp);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}

结果

在这里插入图片描述

看到最后的朋友,如果觉得笔记写的可以,就去右边的侧边栏点个赞!
发布了6 篇原创文章 · 获赞 16 · 访问量 3301

猜你喜欢

转载自blog.csdn.net/qq_35341203/article/details/90115898
今日推荐