1.概述
用DatagramSocket與DatagramPacket實現(xiàn)UDP通信.UDP比TCP相對來說簡單一點,不需要等待連接,且處理數(shù)據(jù)不需要用輸出輸出流,只需要DatagramPacket.嚴格來說,UDP沒有服務(wù)端和客戶端之分,只有發(fā)送端與接收端之分.
2.發(fā)送端
發(fā)送端首先建立DatagramSocket與DatagramPacket,設(shè)置好DatagramPacket的端口與ip,再通過DatagramSocket發(fā)送.
(1)創(chuàng)建DatagramSocket與DatagramPacket
DatagramSocket socket = new DatagramSocket(55555);
這里的55555端口是指數(shù)據(jù)通過這個端口發(fā)送.
(2)創(chuàng)建DatagramPacket
InetAddress ip = InetAddress.getByName("127.0.0.1");
int port = 12345;
String message = "message";
DatagramPacket packet = new DatagramPacket(message.getBytes(),message.getBytes().length,ip,port);
構(gòu)造方法DatagramPacket()的四個參數(shù)分別為 - 發(fā)送的字節(jié)數(shù)組 - 字節(jié)數(shù)組長度 - ip - 端口
這里端口不能與上面的一致,不然的話會提示端口被占用.
(3)發(fā)送
socket.send(packet);
3.接收端
接收端只需指定端口進行接收,這里的端口在DatagramSocket中的構(gòu)造方法中指定,與發(fā)送端的發(fā)送的packet中設(shè)置的端口一致.
(1)創(chuàng)建DatagramSocket
DatagramSocket socket = new DatagramSocket(12345);
(2)創(chuàng)建DatagramPacket
這里創(chuàng)建的DatagramPacket只需要指定存儲數(shù)據(jù)的字節(jié)數(shù)組與該字節(jié)數(shù)組的長度.
byte [] message = new byte[2048];
DatagramPacket packet = new DatagramPacket(message, message.length);
(3)接收
socket.receive(packet);
這個方法會阻塞,直到接收到packet.
(4)獲取數(shù)據(jù)
接收到packet后可以使用getData()獲取數(shù)據(jù),返回字節(jié)數(shù)組,可以傳遞給String的構(gòu)造方法創(chuàng)建String.
String str = new String(packet.getData());
4.完整代碼
這里人為地設(shè)定了客戶端與服務(wù)端,可以互相發(fā)送數(shù)據(jù),服務(wù)端輸入后發(fā)送到服務(wù)端,服務(wù)端返回固定數(shù)據(jù), "客戶端"與"服務(wù)端"輪流扮演了發(fā)送端與接收端的角色.配合了swing使用.
(1)Server.java
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import javax.swing.*;
public class Server
{
public static void main(String[] args)
{
JFrame frame = new JFrame("Server");
JTextArea text = new JTextArea();
frame.add(text);
frame.setSize(600, 300);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
try
{
byte [] message = new byte[2048];
DatagramSocket socket = new DatagramSocket(12345);
DatagramPacket packet = new DatagramPacket(message, message.length);
socket.receive(packet);
InetAddress ip = packet.getAddress();
int port = packet.getPort();
text.setText("ip : "+ip.toString()+"\n");
text.append("port : "+port+"\n");
text.append("message : "+new String(packet.getData()));
String messageFromServer = "Message from server";
packet = new DatagramPacket(messageFromServer.getBytes(),messageFromServer.getBytes().length,ip,port);
socket.send(packet);
socket.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
(2)Client.java
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.Socket;
import javax.swing.*;
import java.awt.GridLayout;
public class Client
{
public static void main(String[] args) {
JFrame frame = new JFrame();
JTextArea text = new JTextArea();
JButton send = new JButton("send");
GridLayout layout = new GridLayout(2,1,1,1);
frame.setLayout(layout);
frame.setTitle("Client");
frame.setVisible(true);
frame.setLocationRelativeTo(null);
frame.setSize(600, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(text);
frame.add(send);
send.addActionListener( v->
{
try
{
InetAddress ip = InetAddress.getByName("127.0.0.1");
int port = 12345;
DatagramSocket socket = new DatagramSocket(55555);
String message = text.getText();
DatagramPacket packet = new DatagramPacket(message.getBytes(),message.getBytes().length,ip,port);
socket.send(packet);
byte [] messageFromServer = new byte[2048];
packet = new DatagramPacket(messageFromServer, messageFromServer.length);
socket.receive(packet);
text.setText(new String(packet.getData()));
socket.close();
}
catch (IOException e)
{
e.printStackTrace();
}
});
}
}