UDP传输:
=DatagramSocket与DatagramPacket
=建立发送端,接受端
=建立数据包
=调用Socket的发送接受方法
=关闭Socket
=发送端和接受端是两个独立运行的程序
发送方代码
public class UDPSender {
public static void main(String[] args) throws IOException {
/*需求:建立UDP的发送端
* 思路:
* 1、建立可以实现UDP传输的socket服务 ——好比货物运输的港口
* 2、明确具体发送的数据 ——要运输的货物
* 3、通过socket服务将具体要发送的数据发送出去
* 4、关闭服务
* */
System.out.print("UDP发送端启动……");
//1、创建UDP服务
DatagramSocket ds = new DatagramSocket();
//2、明确数据
String str = "注意啦,UDP来了";
//3、发送数据,将数据封装到数据包中,数据包会明确目的地和接受端端口
byte[] buf = str.getBytes();
DatagramPacket dp = new DatagramPacket(buf, buf.length,
InetAddress.getByName("192.168.1.102"), 10000);
ds.send(dp);
ds.close();
}
}
接收方代码
public class UDPReceiver {
public static void main(String[] args) throws IOException{
/*创建UDP接收端思路:
* 1、创建socket服务,给接收端明确一个端口
* 2、接受数据
* 3、将其中需要的数据取出来,ip, data ,端口
* 4、关闭资源
* */
System.out.println("UDP接收端启动服务");
DatagramSocket ds = new DatagramSocket(10000);
/*2、使用slcket 接受数据,需要将收到的数据存储在包中,可以根据数据包方法对收到的数据进行解析,
* 得到自己想要的(有数据,地址,端口)。
= 创建数据包
* */
byte buf[] = new byte[1024];//用于接受发送来的数据
DatagramPacket dp = new DatagramPacket(buf, buf.length);//发送过来的内容是二进制码,数组
ds.receive(dp);
//3、通过数据包对象解析数据,先拿到IP地址,再通过Ip地址得到字符串表现形式
String ip=dp.getAddress().getHostAddress(); //得到IP地址
String str=dp.getAddress().getHostName(); //得到主机名
int port=dp.getPort();//获得端口
//获取文字数据 new String(byte())方法可以将字节变成字符串
String data=new String (dp.getData(),0,dp.getLength());
System.out.println(ip+"\t"+str);
System.out.println(data);
ds.close();
}
}
在一个工程里创建聊天室,实现发送接受功能
public class SocketChat {
public static void main(String[] args) throws SocketException {
/*通过UDP协议,完成一个聊天程序
* 一个负责发送数据的任务,一个负责接受数据的任务,两个任务需要同时执行
可以使用多线程技术
* */
//创建socket服务
DatagramSocket send = new DatagramSocket(8888);//确定发送端的端口
DatagramSocket rece = new DatagramSocket(10001);//确定接受端的端口
//开启线程
new Thread(new Send(send)).start();
new Thread(new Receive(rece)).start();
}
}
//负责发送的任务,通过UDPsocket发送
class Send implements Runnable{
//任务对象已建立,就需要Socket对象
private DatagramSocket ds;
public Send(DatagramSocket ds) {
super();
this.ds = ds;
}
@Override
public void run() {
//具体发送数据任务的内容
//1、要发送的数据来自哪里?键盘录入
BufferedReader buf = new BufferedReader(new InputStreamReader(System.in));
//2、将数据封装到数据包中
String line = null;
try {
while((line = buf.readLine()) != null){
if ("over".equals(line)){
break;
}
//2 将数据变成字节数组,封装到包中
byte[] bt=line.getBytes();
DatagramPacket dp=new DatagramPacket(bt,bt. length, InetAddress.getByName("192.168.1.102"), 10001);
//3、将数据包发送出去
ds.send(dp);
}
ds.close();
} catch (IOException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
}
//负责接受的任务
class Receive implements Runnable{
private DatagramSocket ds;
public Receive(DatagramSocket ds) {
super();
this.ds = ds;
}
@Override
public void run() {
while(true){//使用while(true)的原因是要让接收方一直开着
//接受的具体任务内容
//1、因为接受的数据最终都会存储到数据包中,而数据包中必须有字节数组
byte [] buf = new byte[1024];
//2、创建数据包对象
DatagramPacket dp = new DatagramPacket(buf, buf.length);
//3、将收到的数据存储到数据包中
try {
ds.receive(dp);
} catch (IOException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
//4、获取数据
String ip = dp.getAddress().getHostAddress();
String data = new String(dp.getData(),0,dp.getLength());
System.out.print(ip + ":" +data);
//判断是否发出了“over”
if("over".equals(data)){
System.out.println(ip +"……离开了聊天室");
}
}
}
}
记着:发送方打包发送出去的端口要和接收方的端口一致,不然会报出异常错误!