Udp编程的一些练习:
前面我们学习了Udp编程的引入,写的代码有点繁琐,现在我们直接优化改进一下:
package com.westos.Udp;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
/**
* 优化Udp编程
*
*/
public class SendDome {
public static void main(String[] args) throws IOException {
//1)创建Socket对象
DatagramSocket ds=new DatagramSocket();
//2)创建数据并打包
byte[] bys = "我来了,北京".getBytes();
DatagramPacket dp=new DatagramPacket(bys, bys.length,InetAddress.getByName("192.168.43.204"),12345);
//3)发生数据报包
ds.send(dp);
//4)关闭资源
ds.close();
}
}
package com.westos.Udp;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
public class ReceiveDome {
public static void main(String[] args) throws IOException {
//1)创建Socket对象,接收端的Socket对象必须有发送端相对应的端口号
DatagramSocket ds=new DatagramSocket(12345);
//2)创建数据报包
byte[] bys=new byte[1024];
DatagramPacket dp=new DatagramPacket(bys, bys.length);
//3)接收数据报包
ds.receive(dp);
//4)实时分析数据
String data=new String(dp.getData(),0,dp.getLength());
String ip=dp.getAddress().getHostAddress();
//5)输出数据
System.out.println("from"+ip+"data is"+data);
//6)关闭数据
ds.close();
}
}
以上的案例只是可以实现一句话的传输,那么当我们想要进行多句话的传输时应该怎么改进呢?
分析这里讲运用到我们的键盘录入的第二种方法(标准输入流)
package com.westos.Udp02;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
/**
*
* @author 杰哥
*实现发送多条语句
*/
public class SendDome {
public static void main(String[] args) {
try {
//1)创建Socket对象,并且整体给它Try...catch...
DatagramSocket ds=new DatagramSocket();
//2)使用字符串缓冲输出流录入数据(键盘录入的第二种方法)
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
//一次读取一行
/**
* 这里的while循环得把数据报包也包括进去
* 这样可以每读取一句话就去往报包里传输一句话知道over结束
*/
String line=null;
while((line=br.readLine())!=null) {
//判断语句,出现over后就结束输入数据
if("over".equals(line)) {
break;
}
//创建数据报包
DatagramPacket dp=new DatagramPacket(line.getBytes(), line.getBytes().length,InetAddress.getByName("192.168.43.204"),13579);
//发送数据
ds.send(dp);
}
//关闭资源
/**
* 这里的关闭数据必须得写在while循环外面
* 不然当你一句话说完后就已经关闭资源了无法再继续说话
* 就会出现异常:java.net.SocketException: Socket is closed
* 所以我们这里得注意把它放在while循环的外面
*/
ds.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
package com.westos.Udp02;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
public class ReceiveDome {
public static void main(String[] args){
try {
//创建Socket类对象
DatagramSocket ds=new DatagramSocket(13579);
/**
* 这里的while循环是为了不断的接收多条数据
*/
//创建数据报包
byte[] bys=new byte[1024];
DatagramPacket dp=new DatagramPacket(bys, bys.length);
while(true) {
//接收数据
ds.receive(dp);
//解析数据
String line=new String(dp.getData(),0,dp.getLength());
String ip=dp.getAddress().getHostAddress();
//输出数据
System.out.println("from"+ip+"Data is"+line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
以上案例是当我们在发送端输入数据,在接收端接收数据,然后我们还得切换到发送端继续去输入数据,那么有没有可以在一个控制台去输出呢?
分析这里将运用到我们的多线程问题
package com.westos.Udp03;
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 SendDome implements Runnable{
//创建Socket类对象
private DatagramSocket ds;
//创建有参构造
public SendDome (DatagramSocket ds) {
this.ds=ds;
}
@Override
public void run() {
try {
DatagramSocket dsSend=new DatagramSocket();
//创建字符缓冲输入流对象
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
String line=null;
while((line=br.readLine())!=null) {
if("拜拜".equals(line)) {
break;
}
//创建数据报包
DatagramPacket dp=new DatagramPacket
(line.getBytes(), line.getBytes().length,
InetAddress.getByName("192.168.43.204"),10086);
//发生数据报包
ds.send(dp);
}
//关闭数据
dsSend.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
package com.westos.Udp03;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
public class ReceiveDome implements Runnable{
//创建Socket类对象
private DatagramSocket ds;
//有参构造
public ReceiveDome(DatagramSocket ds) {
this.ds=ds;
}
@Override
public void run() {
try {
//创建数据报包
byte[] bys=new byte[1024];
DatagramPacket dp=new DatagramPacket(bys, bys.length);
while(true) {
//去接收它
ds.receive(dp);
//解析数据
String data=new String(dp.getData(),0,dp.getLength());
String ip=dp.getAddress().getHostAddress();
//输出数据
System.out.println("from"+ip+"data is"+data);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//解析数据
}
}
package com.westos.Udp03;
/**
*我们这里是为了创建一个房间可以不断的去接收数据‘
*所以这里我们需要运用到多线程 、IO流等
*
*/
import java.io.IOException;
import java.net.DatagramSocket;
public class ChartRoom {
public static void main(String[] args) throws IOException {
//创建发生端对象和接收端对象
DatagramSocket dsSend=new DatagramSocket();
DatagramSocket dsReceive=new DatagramSocket(10086);
//创建资源类对象
SendDome sd=new SendDome(dsSend);
ReceiveDome rd=new ReceiveDome(dsReceive);
//创建Tread类对象
Thread t1=new Thread(sd);
Thread t2=new Thread(rd);
//启动线程
t1.start();
t2.start();
}
}
Udp编程的原理分析:
1)首先发送端和接收端双方都必须创建Socket对象
2)发送端设置好自己的ip以及端口号后,接收端也得绑定相对于的端口号
3)将需要发送的数据封装进数据报包中,在底层通过流的形式发送给接收方,接收端也创建一个数据报包,去接收发送端接收来的数据,然后去解析数据,最终输出它