UDP接收端
public class UDPReceiveDemo {
public static void main(String[] args) throws IOException{
/**
* 1、建立UDP的socket的服务,必须明白一个端口号
* 2、创建数据包。用于储存接收到的数据,方便用数据包对象的方法解析这些数据
* 3、使用DatagramSocket的receive方法将接收到的数据存储到数据包中
* 4、通过数据包的方法解析数据包中的数据
* 5、关闭socket服务
*/
//udpsocket服务,使用DatagramSocket对象
DatagramSocket ds=new DatagramSocket(10002);
while (true){
//使用DatagramPacket将数据封装到该对象中
byte[] buf=new byte[1024];
DatagramPacket dp=new DatagramPacket(buf, buf.length);
//通过udp的socket服务将数据包发送出去,通过send方法
ds.receive(dp);
//通过数据包的方法解析数据包中的数据,比方。地址、端口、数据内容等
String ip=dp.getAddress().getHostAddress();
int port=dp.getPort();
String text=new String(dp.getData(),0,dp.getLength());
System.out.println(ip+"----------"+port+"-----"+text);
if (text.equals("bye")){
break;
}
}
//关闭资源
ds.close();
}
}
UDP发送端
public class UDPSendDemo {
public static void main(String[] args) throws IOException{
/*
* 1、创建udp传输的发送端
2、建立UDP的socket的服务
3、将要发送的数据封装到数据包中
4、通过udp的socket服务将数据包发送出去
5、关闭socket服务
*/
//udpsocket服务。使用DatagramSocket对象
//监听端口
DatagramSocket ds=new DatagramSocket(8888);
while (true) {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader((System.in)));
String str = bufferedReader.readLine();
//将要发送的数据封装到数据包中
//使用DatagramPacket将数据封装到该对象中
byte[] buf = str.getBytes();
DatagramPacket dp =
new DatagramPacket(buf, buf.length, InetAddress.getByName("127.0.0.1"), 10002);
//通过udp的socket服务将数据包发送出去,通过send方法
ds.send(dp);
if (str.equals("bye")){
break;
}
}
//关闭资源
ds.close();
}
}
采用多线程方式(遇见狂神说,参考网址:https://www.bilibili.com/video/BV1LJ411z7vY?p=11)
public class TalkSend implements Runnable {
DatagramSocket socket = null;
BufferedReader bufferedReader = null;
private int fromPort;
private String toIp;
private int toPort;
public TalkSend(int fromPort, String toIp, int toPort) {
this.fromPort = fromPort;
this.toIp = toIp;
this.toPort = toPort;
try{
socket = new DatagramSocket(fromPort);
bufferedReader = new BufferedReader(new InputStreamReader(System.in));
}catch (Exception e){
e.printStackTrace();
}
}
@Override
public void run() {
while (true) {
String str = null;
try {
str = bufferedReader.readLine();
byte[] buf = str.getBytes();
//将要发送的数据封装到数据包中
//使用DatagramPacket将数据封装到该对象中
DatagramPacket dp =
new DatagramPacket(buf, buf.length, InetAddress.getByName(this.toIp), this.toPort);
socket.send(dp);
if (str.equals("bye")){
break;
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public class TalkReceive implements Runnable{
DatagramSocket socket = null;
private int port;
public TalkReceive(int port) {
this.port = port;
try {
socket = new DatagramSocket(port);
} catch (SocketException e) {
e.printStackTrace();
}
}
@Override
public void run() {
while (true){
try {
//使用DatagramPacket将数据封装到该对象中
byte[] buf=new byte[1024];
DatagramPacket dp=new DatagramPacket(buf, buf.length);
//通过udp的socket服务将数据包发送出去,通过send方法
socket.receive(dp);
String ip=dp.getAddress().getHostAddress();
int port=dp.getPort();
String text=new String(dp.getData(),0,dp.getLength());
System.out.println("From:"+ip+":"+port+"内容为"+text);
if (text.equals("bye")){
break;
}
} catch (IOException e) {
e.printStackTrace();
}
}
//关闭资源
socket.close();
}
}
了解知识
UDP报文没有可靠性保证、顺序保证和流量控制字段等,可靠性较差。但是正因为UDP协议的控制选项较少,在数据传输过程中延迟小、数据传输效率高,适合对可靠性要求不高的应用程序,或者可以保障可靠性的应用程序,如DNS、TFTP、SNMP等。
UDP和TCP区别
TCP | UDP |
---|---|
面向连接 | 面向无接 |
可靠 | 不可靠 |
传输大量数据 | 少量数据 |
慢 | 快 |
总结
1、TCP面向连接(如打电话要先拨号建立连接);UDP是无连接的,即发送数据之前不需要建立连接
2、TCP提供可靠的服务。也就是说,通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP尽最大努力交付,即不保证可靠交付
3、TCP面向字节流,实际上是TCP把数据看成一连串无结构的字节流;UDP是面向报文的,UDP没有拥塞控制,因此网络出现拥塞不会使源主机的发送速率降低(对实时应用很有用,如IP电话,实时视频会议等)
4、每一条TCP连接只能是点到点的;UDP支持一对一,一对多,多对一和多对多的交互通信
5、TCP首部开销20字节;UDP的首部开销小,只有8个字节
6、TCP的逻辑通信信道是全双工的可靠信道,UDP则是不可靠信道