[Java]UDP通信的简单例子

简介:
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);  
        }
    }  
} 
目录
相关文章
|
11月前
|
存储 消息中间件 安全
JUC组件实战:实现RRPC(Java与硬件通过MQTT的同步通信)
【10月更文挑战第9天】本文介绍了如何利用JUC组件实现Java服务与硬件通过MQTT的同步通信(RRPC)。通过模拟MQTT通信流程,使用`LinkedBlockingQueue`作为消息队列,详细讲解了消息发送、接收及响应的同步处理机制,包括任务超时处理和内存泄漏的预防措施。文中还提供了具体的类设计和方法实现,帮助理解同步通信的内部工作原理。
JUC组件实战:实现RRPC(Java与硬件通过MQTT的同步通信)
|
10月前
|
Java
JAVA多线程通信:为何wait()与notify()如此重要?
在Java多线程编程中,`wait()` 和 `notify()/notifyAll()` 方法是实现线程间通信的核心机制。它们通过基于锁的方式,使线程在条件不满足时进入休眠状态,并在条件满足时被唤醒,从而确保数据一致性和同步。相比其他通信方式,如忙等待,这些方法更高效灵活。 示例代码展示了如何在生产者-消费者模型中使用这些方法实现线程间的协调和同步。
108 3
|
11月前
|
安全 Java
Java多线程通信新解:本文通过生产者-消费者模型案例,深入解析wait()、notify()、notifyAll()方法的实用技巧
【10月更文挑战第20天】Java多线程通信新解:本文通过生产者-消费者模型案例,深入解析wait()、notify()、notifyAll()方法的实用技巧,包括避免在循环外调用wait()、优先使用notifyAll()、确保线程安全及处理InterruptedException等,帮助读者更好地掌握这些方法的应用。
145 1
|
11月前
|
安全 Java 开发者
Java多线程中的`wait()`、`notify()`和`notifyAll()`方法,探讨了它们在实现线程间通信和同步中的关键作用
本文深入解析了Java多线程中的`wait()`、`notify()`和`notifyAll()`方法,探讨了它们在实现线程间通信和同步中的关键作用。通过示例代码展示了如何正确使用这些方法,并分享了最佳实践,帮助开发者避免常见陷阱,提高多线程程序的稳定性和效率。
211 1
|
11月前
|
Java
在Java多线程编程中,`wait()` 和 `notify()/notifyAll()` 方法是线程间通信的核心机制。
在Java多线程编程中,`wait()` 和 `notify()/notifyAll()` 方法是线程间通信的核心机制。它们通过基于锁的方式,使线程在条件不满足时进入休眠状态,并在条件成立时被唤醒,从而有效解决数据一致性和同步问题。本文通过对比其他通信机制,展示了 `wait()` 和 `notify()` 的优势,并通过生产者-消费者模型的示例代码,详细说明了其使用方法和重要性。
139 1
|
11月前
|
Java
|
11月前
|
网络协议 Linux 网络性能优化
Linux C/C++之TCP / UDP通信
这篇文章详细介绍了Linux下C/C++语言实现TCP和UDP通信的方法,包括网络基础、通信模型、编程示例以及TCP和UDP的优缺点比较。
425 0
Linux C/C++之TCP / UDP通信
|
11月前
|
Java
用java实现Client和Server之间的互相通信
本文介绍了如何使用Java实现客户端和服务器之间的通信,包括服务器端创建ServerSocket、接受客户端连接、读取和发送消息,以及客户端创建Socket连接、发送和接收消息的完整过程。
362 0
用java实现Client和Server之间的互相通信
|
11月前
|
JavaScript 安全 Java
谈谈UDP、HTTP、SSL、TLS协议在java中的实际应用
下面我将详细介绍UDP、HTTP、SSL、TLS协议及其工作原理,并提供Java代码示例(由于Deno是一个基于Node.js的运行时,Java代码无法直接在Deno中运行,但可以通过理解Java示例来类比Deno中的实现)。
212 1
|
C语言
C语言 网络编程(七)UDP通信创建流程
本文档详细介绍了使用 UDP 协议进行通信的过程,包括创建套接字、发送与接收消息等关键步骤。首先,通过 `socket()` 函数创建套接字,并设置相应的参数。接着,使用 `sendto()` 函数向指定地址发送数据。为了绑定地址,需要调用 `bind()` 函数。接收端则通过 `recvfrom()` 函数接收数据并获取发送方的地址信息。文档还提供了完整的代码示例,展示了如何实现 UDP 的发送端和服务端功能。