文章目录
- UDP的特点
- 无连接的
- 不可靠性
- 面向报文
- 阻塞控制
- 实现UDP通信需要的类和方法
- DatagramSocket API
- DatagramPacket API
- 构造方法
- DatagramPacket 常用方法
- InetSocketAddress API
- 实现UDP通讯的代码
- UDP 服务器
- UDP客户端
UDP的特点
无连接的
首先UDP是无连接的,什么是无连接的呢?无连接的意思就是在发送消息的过程中发消息的一方和收消息的一方都不会保存对方的信息。因此我们说他是无连接的,既然是无连接的那么每一次我们发送的消息其实这个信息中不止包含我们想要发送的消息,还包含了对方的IP地址和端口号以及自己的IP地址和端口号。因此就涉及到了另一个特性那就是面向报文传输
不可靠性
不可靠性,为什么说UDP传输时不可靠的呢?这要跟他的传输方式有关因为UDP的传输时尽自己最大能力的传输消息因此它并不保证这个消息能够准确并且完整的传输到对方的手中因此我们说他是不可靠的。
面向报文
面向报文传输。这里跟我们的无连接性其实是有关系的,由于UDP是没有连接的即不会保存通信双方的信息,因此每一次的发送都需要我们将要发送的数据以及发送方的IP地址端口号以及接受方的IP地址端口号进行打包。
阻塞控制
UDP没有拥塞控制,因此网络出现的拥塞不会使源主机的发送速率降低。很多的实时应用(如IP电话、实时视频会议等)要去源主机以恒定的速率发送数据,并且允许在网络发生拥塞时丢失一些数据,但却不允许数据有太多的时延。UDP正好符合这种要求。
实现UDP通信需要的类和方法
DatagramSocket API
DatagramSocket 是UDP Socket,用于发送和接收UDP数据报。
DatagramSocket 构造方法
方法签名 | 方法使用 |
---|---|
DatagramSocket() | 创建一个UDP数据报套接字的Socket,绑定到本机任意一个随机端口(一般用于客户端) |
DatagramSocket(int port) | 创建一个UDP数据报套接字的Socket,绑定到本机指定的端口(一般用于服务端) |
DatagramSocket 方法
方法签名 | 方法使用 |
---|---|
void receive(DatagramPacket p) | 从此套接字接收数据报(如果没有接收到数据报,该方法会阻塞等待) |
void send(DatagramPacketp) | 从此套接字发送数据报包(不会阻塞等待,直接发送) |
void close() | 关闭此数据报套接字 |
DatagramPacket API
DatagramPacket 类是用来保存UDP通讯中发送和接受的数据报
构造方法
方法名称 | 方法说明 |
---|---|
DatagramPacket(byte[]buf, int length) | 构造一个DatagramPacket 对象并且内部传入一个字节数组,我们要接受的信息全部都存入到这个字节数组中,接受的内容存储在第一个参数buf中接受的指定长度为第二个参数 |
DatagramPacket(byte[]buf, int offset, int length,SocketAddress address) | 构造一个DatagramPacket 对象用来发送数据发送的数据内容存储在第一个参数buf中发送的数据是字节长度存储到第二个和第三个参数中,最后一个参数address用来存储目标的IP地址和端口号 |
DatagramPacket 常用方法
方法签名 | 方法说明 |
---|---|
InetAddress getAddress() | 从接收的数据报中,获取发送端主机IP地址;或从发送的数据报中,获取接收端主机IP地址 |
int getPort() | 从接收的数据报中,获取发送端主机的端口号;或从发送的数据报中,获取接收端主机端口号 |
byte[] getData() | 获取数据报中的数据 |
构造UDP发送的数据报时,需要传入 SocketAddress ,该对象可以使用 InetSocketAddress 来创
建。
InetSocketAddress API
InetSocketAddress ( SocketAddress 的子类 )构造方法:
方法签名 | 方法说明 |
---|---|
InetSocketAddress(InetAddress addr, int port) | 创建一个Socket地址,包含IP地址和端口号 |
实现UDP通讯的代码
UDP 服务器
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
class UDPserver{private DatagramSocket socket=null;public UDPserver(int port) throws SocketException {socket=new DatagramSocket(port);}public void start() throws IOException {System.out.println("服务器正常启动");while(true){//接收请求DatagramPacket requestPacket =new DatagramPacket(new byte[1024],1024);socket.receive(requestPacket);String reques=new String(requestPacket.getData(),0,requestPacket.getLength());//创建回应信息String Response=po(reques);DatagramPacket responsePacket=new DatagramPacket(Response.getBytes(),0,Response.getBytes().length,requestPacket.getSocketAddress());socket.send(responsePacket);System.out.printf("[%s,%s,%s,%d]:%s",requestPacket.getAddress(),"发送到",responsePacket.getAddress(),requestPacket.getPort(),Response);}}public String po(String s){return s;}
}public class Udpsever {public static void main(String[] args) throws IOException {UDPserver udPserver=new UDPserver(9090);udPserver.start();}
}
UDP客户端
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.util.Scanner;class UDPclient{private DatagramSocket datagramSocket=null;private String IP;private int Port;public UDPclient(String Ip,int port) throws SocketException {IP=new String(Ip);Port=port;datagramSocket=new DatagramSocket();}public void start() throws IOException {while(true){System.out.print("请输入你的请求->");Scanner scanner=new Scanner(System.in);String reques=scanner.nextLine();DatagramPacket requesgramPacket=new DatagramPacket(reques.getBytes(), reques.getBytes().length,InetAddress.getByName(IP),Port);DatagramPacket responsegramPacket=new DatagramPacket(new byte[1024],1024);datagramSocket.send(requesgramPacket);datagramSocket.receive(responsegramPacket);String responce=new String(responsegramPacket.getData(),0,responsegramPacket.getLength());System.out.println("response:"+responce);}}
}
public class Main {public static void main(String[] args) throws IOException {UDPclient udPclient=new UDPclient("127.0.0.1",9090);udPclient.start();}
}