udp面向非连接,是一种传输层协议,提供面向事务的简单不可靠信息传送服务,例如视频聊天,游戏卡顿
由传输层到达应用层需要套接字 Socket
手写了一下模拟udp传输协议
注意端口不能重复
发送端:
package cn.net.java.mhz;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
/**
* 注意端口被占用的问题 同一个协议下端口不允许重复
* udp编程:一切以包裹为中心
* udp不安全,存在丢包,但是性能效率比较高
* udp可能将一个数据分成多个数组来传输
* udp发送端和接收端地位平等
*
* DatagramSocket:用于发送或接收数据包的套接字
* DatagreamPacket:数据包
*
* @author MHZ
*
* 基本流程:
* 发送端
*1.使用DatagramSocket 指定端口 创建发送端
* 2.准备容器
* 3.封装成DatagramPacket包裹,指定目的地
* 4.发送包裹 send
* 5.释放资源
*
*
*/
public class MyUDPSocket {
public static void main(String[] args) throws Exception {
System.out.println("发送方启动中........");
//1.使用DatagramSocket 指定端口 创建接收端
DatagramSocket client = new DatagramSocket(6666);
//2.准备容器 把要传送的数据写成字节数组的形式
String data = "MHZ";
byte[] datas = data.getBytes();
//3.封装成DatagramPacket包裹,指定目的地
DatagramPacket packet = new DatagramPacket(datas,0,datas.length,new InetSocketAddress("localhost",8888));
//4.发送包裹
client.send(packet);
// 5.释放资源
client.close();
}
}
接收端:
package cn.net.java.mhz;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.SocketException;
/**
* Udp编程
* @author MHZ
*
* 基本流程:
* 接收端
*1.使用DatagramSocket 指定端口 创建接收端
* 2.准备容器 封装成DatagramPacket包裹
* 3.阻塞式接收包裹
* 4.分析数据
* byte[] getData()
* getLength()
* 5.释放资源
*
*/
public class MyUDPSocketSever {
public static void main(String[] args) throws Exception {
System.out.println("接收方启动中........");
//1.使用DatagramSocket 指定端口 创建接收端
DatagramSocket server = new DatagramSocket(8888);
//2.准备容器 封装成DatagramPacket包裹
byte[] container = new byte[1024*60];
DatagramPacket packet = new DatagramPacket(container,0,container.length);
//3.阻塞式接收包裹
server.receive(packet);
//4.分析数据
byte[] datas = packet.getData();
int len = packet.getLength();
System.out.println(new String(datas,0,len));
// 5.释放资源
server.close();
}
}
实现一个学生与老师的互动交流的聊天功能,一边作为发送端,一边作为接收端,需要用到多线程的知识
首先要实现多次交流,使用到循环和控制台
package cn.net.java.mhz;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
/**
* 实现多次发送,多次接收
* @author MHZ
*
*/
public class UdpClientTalk {
public static void main(String[] args) throws Exception {
System.out.println("发送方启动中........");
// 1.使用DatagramSocket 指定端口 创建接收端
DatagramSocket client = new DatagramSocket(7777);
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
while (true) {
// 2.准备容器 把要传送的数据写成字节数组的形式
String data = br.readLine();
byte[] datas = data.getBytes();
// 3.封装成DatagramPacket包裹,指定目的地 地址+端口
DatagramPacket packet = new DatagramPacket(datas, 0, datas.length,
new InetSocketAddress("localhost", 9999));
// 4.发送包裹
client.send(packet);
if(data.equals("bye")) {
break;
}
}
client.close();
br.close();
}
}
package cn.net.java.mhz;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
/**
* 实现多次发送,多次接收
* @author MHZ
*
*/
public class UdpSeverTalk {
public static void main(String[] args) throws Exception {
System.out.println("接收方启动中........");
// 1.使用DatagramSocket 指定端口 创建接收端
DatagramSocket server = new DatagramSocket(9999);
while (true) {
// 2.准备容器 封装成DatagramPacket包裹
byte[] container = new byte[1024 * 60];
DatagramPacket packet = new DatagramPacket(container, 0, container.length);
// 3.阻塞式接收包裹
server.receive(packet);
// 4.分析数据
byte[] datas = packet.getData();
int len = packet.getLength();
String data = new String(datas, 0, len);
System.out.println(data);
if(data.equals("bye")) {
break;
}
}
// 5.释放资源
server.close();
}
}
接着实现两个多线程类,实现了Runnable接口,重写run方法,利用了上面写出的两个多次交流的类
发送端:
package cn.net.java.mhz;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.SocketException;
/**
* 实现多线程的udp编程,实现一个简单的聊天功能
* 发送端
* @author MHZ
*
*/
public class UdpTalkSend implements Runnable{
private DatagramSocket client;
private int port;
private String toIP;
private int toPort;
private BufferedReader br;
public UdpTalkSend(int port,String toIP,int toPort)
{
this.port = port;
this.toIP = toIP;
this.toPort = toPort;
this.br = new BufferedReader(new InputStreamReader(System.in));
try {
client = new DatagramSocket(port);
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
public void run() {
while (true) {
// 2.准备容器 把要传送的数据写成字节数组的形式
String data;
try {
data = br.readLine();
byte[] datas = data.getBytes();
// 3.封装成DatagramPacket包裹,指定目的地 地址+端口
DatagramPacket packet = new DatagramPacket(datas, 0, datas.length,
new InetSocketAddress(this.toIP, this.toPort));
// 4.发送包裹
client.send(packet);
if (data.equals("bye")) {
break;
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//关闭资源
this.client.close();
}
}
接收端:
package cn.net.java.mhz;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
/**
* 实现多线程的udp编程
* 接收端
* @author MHZ
*
*/
public class UdpTalkReceive implements Runnable{
// 1.使用DatagramSocket 指定端口 创建接收端
private DatagramSocket server;
private int port;
private String from;
public UdpTalkReceive(int port,String from)
{
this.port = port;
this.from = from;
try {
this.server = new DatagramSocket(port);
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
public void run() {
while (true) {
// 2.准备容器 封装成DatagramPacket包裹
byte[] container = new byte[1024 * 60];
DatagramPacket packet = new DatagramPacket(container, 0, container.length);
// 3.阻塞式接收包裹
try {
server.receive(packet);
// 4.分析数据
byte[] datas = packet.getData();
int len = packet.getLength();
String data = new String(datas, 0, len);
System.out.println(this.from + ":" + data);
if (data.equals("bye")) {
break;
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// 5.释放资源
this.server.close();
}
}
最后调用这两个类,实现功能并测试
package cn.net.java.mhz;
/**
* 实现一个基于udp协议的在线咨询
* @author MHZ
*
*/
public class TalkStudent {
public static void main(String[] args) {
//多线程,学生既可以作为发送者,也可以作为接收者
new Thread(new UdpTalkSend(2222,"localhost",5555)).start(); //作为发送者的线程
new Thread(new UdpTalkReceive(1111,"老师")).start(); //作为接收者的线程
}
}
package cn.net.java.mhz;
/**
* 实现一个基于udp协议的在线咨询
* @author MHZ
*
*/
public class TalkTeacher {
public static void main(String[] args) {
new Thread(new UdpTalkReceive(5555,"学生")).start();
new Thread(new UdpTalkSend(3333,"localhost",1111)).start(); //作为发送者的线程
}
}