前面写了Socket的TCP编程,这种是面向连接的,比较耗时,UDP是面向无连接的。TCP和UDP同属于运输层,各有各的好处,TCP一等程度能保证数据包的准确率,UDP比TCP稳定性差点,但在实际的需求中往往就需要用到UDP数据,如在线实时语音和视频时,在保证速度的前提下部分的数据丢失所造成的影响不大。但如果使用TCP协议,为了等待个别数据包而导致请求重传或等待数据包所造成的停顿是无法接受的。
Java中UDP通过两个类来实现:
DatagramPacket类 和 DatagramSocket类DatagramPacket类用于将数据字节填充到其中的UDP包中,用于发送和解包接受的数据包。
DatagramSocket类用于将数据UDP包进行发送和接受操作等。
客户端代码:
public class Client {
private static String IP = "127.0.0.1";
private static int PORT = 10000;
public static void main(String args[]) throws SocketException{
SendThread sendThread = new SendThread();
sendThread.start();
ReceiveThread receiveThread = new ReceiveThread(sendThread.client_socket);
receiveThread.start();
}
static class SendThread extends Thread{
//客户端socket
public DatagramSocket client_socket;
public SendThread()throws SocketException{
client_socket = new DatagramSocket();
//连接到默认的服务器
client_socket.connect(new InetSocketAddress(IP, PORT));
}
public void run(){
while (true) {
System.out.print("请输入要发送的信息: ");
//标准输入流
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
try {
String inputLine = br.readLine();
byte[] data = inputLine.getBytes();
//将数据封装到udp数据包中,包括字节数据,服务端的地址和端口
DatagramPacket datagramPacket = new DatagramPacket(data, data.length, client_socket.getInetAddress(), client_socket.getPort());
client_socket.send(datagramPacket);
try {
this.sleep(1000);
}catch (InterruptedException e){
e.printStackTrace();
}
}catch (IOException e){
e.printStackTrace();
}
}
}
}
static class ReceiveThread extends Thread{
DatagramSocket datagramSocket;
public ReceiveThread(DatagramSocket datagramSocket)throws SocketException{
this.datagramSocket = datagramSocket;
}
public void run(){
byte[] data = new byte[65536];
//接收包
DatagramPacket datagramPacket = new DatagramPacket(data, 0, data.length);
while(true){
try{
datagramSocket.receive(datagramPacket);
String content = new String(datagramPacket.getData(),0,datagramPacket.getLength());
System.out.print("from:"+datagramPacket.getAddress()+"/port:"+datagramPacket.getPort()+"内容"+content+"\n");
}catch (IOException e){
e.printStackTrace();
}
}
}
}
}
服务器端代码:
public class Server {
private static int PORT = 10000;//指定端口号
public static void main(String args[])throws SocketException{
HandleData handleData = new HandleData();
handleData.start();
}
static class HandleData extends Thread{
public DatagramSocket serverSocket;
public HandleData()throws SocketException{
//创建服务器端socket
serverSocket = new DatagramSocket(PORT);
}
public void run(){
byte[] data = new byte[65535];//设置最大字节
while (true){
try {
//接收包
DatagramPacket datagramPacket = new DatagramPacket(data, 0, data.length);
serverSocket.receive(datagramPacket);
//获取客户端ip和port
InetAddress client_ip = datagramPacket.getAddress();
int client_port = datagramPacket.getPort();
String content = new String(datagramPacket.getData(),0,datagramPacket.getLength());
System.out.print("from:"+client_ip+"/port:"+client_port+": "+content+"\n");
//回复
String replyContent = content.toUpperCase();
byte[] replyData = replyContent.getBytes();
//发送包
DatagramPacket replydp = new DatagramPacket(replyData,0,replyData.length,client_ip,client_port);
serverSocket.send(replydp);
}catch (IOException e){
e.printStackTrace();
}
}
}
}
}
客户端:
服务器端: