[Java]UDP通信的简单例子

最后更新于:2022-04-01 09:59:21

~~~ package com.sjf; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.SocketException; /** * @time 2015-05-27 * @desc UDP通信 * @author sjf0115 * */ public class Server { private byte[] buffer = new byte[1024]; private DatagramSocket socket = null; private DatagramPacket packet = null; private InetSocketAddress socketAddress = null; private InetAddress clientAddress; private String clientIP; private int clientPort; private String clientData; //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ /** * 构造函数,绑定主机和端口. * @param ip IP 地址 * @param port 端口 * @throws Exception */ public Server(String ip, int port) throws Exception { // 绑定IP地址和端口. Bind(ip,port); System.out.println("[服务端启动]"); } //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ public Server() throws SocketException { // 构造数据报套接字并将其绑定到本地主机上任何可用的端口 socket = new DatagramSocket(); System.out.println("[服务端启动]"); } //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ /** * 绑定监听地址和端口. * @param ip IP地址 * @param port 端口 * @throws SocketException */ public void Bind(String ip, int port) throws SocketException { // 根据 IP 地址和端口号创建套接字地址 socketAddress = new InetSocketAddress(ip, port); // 创建数据报套接字,将其绑定到指定的本地地址 socket = new DatagramSocket(socketAddress); packet = new DatagramPacket(buffer, buffer.length); } //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ public final String getOrgIp() { return clientIP; } //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ /** * 设置超时时间 * @param timeout 超时时间 * @throws Exception */ public void SetTimeout(int timeout) throws Exception { /* 启用/禁用带有指定超时值的 SO_TIMEOUT,以毫秒为单位。 * 将此选项设为非零的超时值时,对此 DatagramSocket 调用 receive() 将只阻塞此时间长度。 * 如果超过超时值,将引发 java.net.SocketTimeoutException,虽然 DatagramSocket 仍旧有效。 * 选项必须在进入阻塞操作前被启用才能生效。 */ socket.setSoTimeout(timeout); } //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ /** * 获得超时时间. * @return 返回超时时间. * @throws Exception */ public int GetTimeout() throws Exception { return socket.getSoTimeout(); } //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ /** * 接收数据包,该方法会造成线程阻塞. * @return 返回接收的数据串信息 * @throws IOException */ public String Receive() throws IOException { /* * 从此套接字接收数据报包。当此方法返回时,DatagramPacket 的缓冲区填充了接收的数据。 * 数据报包也包含发送方的 IP 地址和发送方机器上的端口号。此方法在接收到数据报前一直阻塞。 * 数据报包对象的 length 字段包含所接收信息的长度。如果信息比包的长度长,该信息将被截短。 */ socket.receive(packet); // 数据报包包含发送方的 IP 地址 clientAddress = packet.getAddress(); clientIP = clientAddress.getHostAddress(); // 数据报包包含发送方的端口号 clientPort = packet.getPort(); // 数据报包包含发送方的数据 clientData = new String(packet.getData(), 0, packet.getLength()); return " ["+clientData+"]"; } //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ /** * 将响应包发送给请求端. * @param bytes 回应报文 * @throws IOException */ public void Send(String info) throws IOException { packet.setAddress(clientAddress); packet.setPort(clientPort); packet.setData(info.getBytes()); /* * 从此套接字发送数据报包。DatagramPacket 包含的信息指示:将要发送的数据、其长度、远程主机的 IP 地址和远程主机的端口号。 */ socket.send(packet); } //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ /** * 关闭udp监听口. */ public void close() { try { socket.close(); } catch (Exception ex) { ex.printStackTrace(); } } //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ /** * 测试方法. * @param args * @throws Exception */ public static void main(String[] args) throws Exception { String serverHost = "127.0.0.1"; int serverPort = 3344; Server udpServerSocket = new Server(serverHost, serverPort); while (true) { String info = udpServerSocket.Receive(); System.out.println("["+udpServerSocket.clientPort+"]->"+info); udpServerSocket.Send("Reponse-----"+info); } } } ~~~ ~~~ package com.sjf; import java.io.*; import java.net.*; /** * @time 2015-05-27 * @desc UDP通信 * @author QPING */ public class Client { private byte[] buffer = new byte[1024]; private DatagramSocket socket = null; private InetSocketAddress socketAddress = null; private String clientIP; private int clientPort; private String clientData; private InetAddress clientAddress; private DatagramPacket sendPacket; private DatagramPacket receivePacket; //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ public Client(String host, int port) throws Exception { // 根据 IP 地址和端口号创建套接字地址 socketAddress = new InetSocketAddress(host, port); // 创建数据报套接字,将其绑定到指定的本地地址 socket = new DatagramSocket(socketAddress); System.out.println("服务端启动!"); } //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ /** * 构造函数,创建UDP客户端 * @throws Exception */ public Client() throws Exception { socket = new DatagramSocket(); } //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ /** * 设置超时时间,该方法必须在bind方法之后使用. * @param timeout 超时时间 * @throws Exception */ public final void SetTimeout(final int timeout) throws Exception { socket.setSoTimeout(timeout); } //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ /** * 获得超时时间. * @return 返回超时时间 * @throws Exception */ public int GetTimeout() throws Exception { return socket.getSoTimeout(); } //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ public DatagramSocket GetSocket() { return socket; } //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ /** * 向指定的服务端发送数据信息. * @param ip 服务器主机地址 * @param port 服务端端口 * @param bytes 发送的数据信息 * @return 返回构造后俄数据报 * @throws IOException */ public DatagramPacket Send(String ip,int port,String info) throws IOException { byte[] bytes = info.getBytes(); sendPacket = new DatagramPacket(bytes, bytes.length); sendPacket.setAddress(InetAddress.getByName(ip)); sendPacket.setPort(port); socket.send(sendPacket); return sendPacket; } //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ /** * 接收从指定的服务端发回的数据. * @param lhost 服务端主机 * @param lport 服务端端口 * @return 返回从指定的服务端发回的数据. * @throws Exception */ public String Receive(String lhost,int lport) throws Exception { receivePacket = new DatagramPacket(buffer, buffer.length); socket.receive(receivePacket); // 数据报包包含发送方的 IP 地址 clientAddress = receivePacket.getAddress(); clientIP = clientAddress.getHostAddress(); // 数据报包包含发送方的端口号 clientPort = receivePacket.getPort(); // 数据报包包含发送方的数据 clientData = new String(receivePacket.getData(), 0, receivePacket.getLength()); return "["+clientData+"]"; } //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ /** * 关闭udp连接. */ public void close() { try { socket.close(); } catch (Exception ex) { ex.printStackTrace(); } } //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ /** * 测试客户端发包和接收回应信息的方法. * @param args * @throws Exception */ public static void main(String[] args) throws Exception { String serverHost = "127.0.0.1"; int serverPort = 3344; String myIP = "127.0.0.2"; int myPort = 3333; Client client = new Client(myIP,myPort); while(true) { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); System.out.println("["+myPort+"] "); String str = br.readLine(); client.Send(serverHost, serverPort, str); String info = client.Receive(serverHost, serverPort); System.out.println("["+client.clientPort+"]->" + info); } } } ~~~
';