UDP传送方式
发送端:
1.使用datagramSocket 创建发送端 指定端口1
2.准备数据转成字节数组
3.封装成datagrampacket包裹,需要指定目的地的端口2
4.发送包裹send(datagramPacket p)
5.释放资源
接收端:
1.使用datagramSocket 创建接收端 指定端口2(与发送端的包裹端口一致)
2.准备容器 封装成datagrampacket包裹
3.阻塞式接收包裹receive(datagramPacket p)
4.分析数据 字节数组
5.释放资源
代码:
1.使用datagramSocket 创建发送端 指定端口
DatagramSocket client = new DatagramSocket(8887);
//2.准备数据转成字节数组
String data = "上海三学堂";
byte[] datas = data.getBytes();
//3.封装成datagrampacket包裹,需要指定目的地
DatagramPacket packet = new DatagramPacket(datas,0,datas.length,
new InetSocketAddress("localhost",6666));
//4.发送包裹send(datagramPacket p)
client.send(packet);
//5.释放资源
client.close();
2.使用datagramSocket 创建接收端 指定端口
DatagramSocket server = new DatagramSocket(6666);
//2.准备容器 封装成datagrampacket包裹
byte[] container = new byte[1024];
DatagramPacket packet = new DatagramPacket(container, 0,container.length);
//3.阻塞式接收包裹receive(datagramPacket p)
server.receive(packet);
//4.分析数据 字节数组 byte[] getData() getLength()
byte[] datas = packet.getData();
int len = packet.getLength();
System.out.println(new String(datas,0,len));
//5.释放资源
server.close();
上面的方法是传入字符串,直接可以转成字节数组去对接,对于发送基本类型和文件等形式的数据,则需要先利用IO流转成对应的字节数组,然后才能发送,接收到的字节数组也要转化成原来的文件类型。
Udp传送基本类型的数据:
发送端的数据写入需要修改为:
//2.准备数据转成字节数组
//写出
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(baos));
dos.writeInt(18);
dos.writeBoolean(true);
dos.writeChar('a');
dos.flush();
byte[] datas = baos.toByteArray();
接收端的数据读取需要修改为:
//读取
DataInputStream dis = new DataInputStream(new BufferedInputStream(new ByteArrayInputStream(datas)));
int a = dis.readInt();
boolean b = dis.readBoolean();
System.out.println(a+" "+b);
如果需要传送文件则需要引入类方法IOUtils:
//写入端:
byte[] datas = IOutils.fileToByteArray("src/ww.jpg");
//读取端:
IOutils.ByteArrayTofile(datas, "src/copy.png");
UDP协议的在线咨询小项目
上面的数据交流是单方向单线程的一次传输,要实现在线咨询,需要克服两个点:
1.多次交流,则要对发送和接收这两个行为外面加入死循环,以关键词标识输入来结束循环,达到多次发送多次接收的目的。
2.双向的交流,则需要利用多线程,在发的同时对方也能发,这就需要把发送端和接收端封装成两个线程类,然后重新建立两个类,在里面分别加入发送线程和接收线程,注意端口不要冲突。
源代码如下:
发送端的线程类:
public class UdpClientThread implements Runnable{
private DatagramSocket clien;
InetSocketAddress inet; //建立端口对象,在设置包裹时用到
public UdpClientThread (int x,String s,int x1) throws SocketException {
clien = new DatagramSocket(x);
inet = new InetSocketAddress(s,x1);
}
public void run() { //线程体
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
while(true) { //死循环不停接收
String s;
try {
s = reader.readLine();
byte[] datas = s.getBytes();
DatagramPacket packet = new DatagramPacket(datas,0,datas.length,
inet);
clien.send(packet);
if(s.equals("bye"))break; // 关键词标识
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}}
接收端的线程类:
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
public class UdpServerThread implements Runnable {
DatagramSocket serve;
private String people; //传入对象的名字
public UdpServerThread(int z,String x) throws SocketException {
serve = new DatagramSocket(z);
this.people = x; //传入对象的名字
}
@Override
public void run() {
while(true) {
byte[] datas = new byte[1024];
DatagramPacket packet = new DatagramPacket(datas, 0,datas.length);
try {
serve.receive(packet);
byte[] s = packet.getData();
String data = new String(s,0,s.length);
System.out.println(people+"说"+data);
if(data.equals("bye"))break;
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
然后就建立两个类,分别加入上面的两个线程体
————————————————-------------------
student类:
import java.net.SocketException;
public class finalstudent {
public static void main(String[] args) throws SocketException {
UdpClientThread u = new UdpClientThread(6666,"localhost",9999);
new Thread(u).start();
UdpServerThread m = new UdpServerThread(7878,"老师");
new Thread(m).start();
}
}
teacher类:
import java.net.SocketException;
public class finalteacher {
public static void main(String[] args) throws SocketException {
UdpServerThread u = new UdpServerThread(9999,"学生");
new Thread(u).start();
UdpClientThread m = new UdpClientThread(7777,"localhost",7878);
new Thread(m).start();
}
}
效果图如下: