Java网络编程 - UDP

2018-08-02  本文已影响5人  BlueSkyBlue

UDP传输

发送端和接收端是两个独立运行的程序。

类DatagramSocket

此类表示用来发送和接收数据报包的套接字。

方法 方法简介
void receive(DatagramPacket p) 从此套接字接收数据报包。
void send(DatagramPacket p) 从此套接字发送数据报包。

类DatagramPacket

数据报包用于实现无连接的包投递服务。每条报文仅根据包中包含的信息从一台机器路由到另一台机器。
构造方法:

UDP发送数据流程

  1. 建立UDP socket服务。
  2. 提供数据并将数据封装到数据包中。
  3. 通过socket服务的发送功能将数据包发送出去。
  4. 关闭资源。
public static void main(String[] args) throws Exception {
        //通过Datagramsocket对象创建UDP服务
        DatagramSocket ds = new DatagramSocket();
        //确定数据并封装成数据包
        byte [] data = "UDP, I am coming.".getBytes();
        DatagramPacket datap = new DatagramPacket(data, data.length, InetAddress.getByName("自己本机的IP地址"),10000);
        //通过Socket服务将已有的数据包发送出去
        ds.send(datap);
        //关闭资源
        ds.close();
}

由于没有接收端,因此该程序发送的数据丢失。

UDP接收端

  1. 定义UDP的Socket服务。
  2. 定义一个数据包DatagramPacket,用于存储接收到的字节数据。数据包对象中有更多功能可以提取字节信息中的不同信息。
  3. 通过Socket服务的receive方法将收到的数据存储到定义好的数据包中。
    4.通过数据包对象中的特有功能将数据取出。
  4. 对数据进行处理。
  5. 关闭资源。

定义UDP接收端的时候通常会监听一个端口,其实就是给这个网络应用程序定义一个数字标识。如果不定义系统会分配一个随机的。方便于明确哪些数据过来该应用程序可以处理。接收端通常会指定一个监听端口。

public static void main(String[] args) throws Exception{
        //创建UDP的Scoket服务,建立端点。同时指定监听端口为10000。
        DatagramSocket ds = new DatagramSocket(10000);
        //定义数据包用于存储数据。
        byte [] buffer = new byte[1024];
        DatagramPacket datap = new DatagramPacket(buffer, buffer.length);
        //通过服务的receive方法将收到的数据存入数据包中
        ds.receive(datap);
        //通过数据包的方法获取其中的数据
        String IP = datap.getAddress().getHostAddress();
        String data = new String(datap.getData(), 0, datap.getLength());
        int port = datap.getPort();
        System.out.println(IP);
        System.out.println(data);
        System.out.println(port);
        //关闭端口
        ds.close();
}

键盘输入发送

发送端

public static void main(String[] args) throws Exception {
        //通过Datagramsocket对象创建UDP服务
        DatagramSocket ds = new DatagramSocket();
        //键盘录入
        BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
        String line = null;
        while((line = bufr.readLine())!= null){
            if(line.equals("886")){
                break;
            }
            byte [] buffer = line.getBytes();
            DatagramPacket datap = new DatagramPacket(buffer, buffer.length, InetAddress.getByName("输入要发送的机器的IP地址"), 10001);
            ds.send(datap);
        }
        ds.close();
}

接收端

public static void main(String[] args) throws Exception{
        DatagramSocket ds = new DatagramSocket(10001);
        while(true){
            byte [] buffer = new byte[1024];
            DatagramPacket datap = new DatagramPacket(buffer, buffer.length);
            ds.receive(datap);
            String ip = datap.getAddress().getHostAddress();
            String data = new String(datap.getData(), 0, datap.getLength());
            System.out.println("ip:" + ip + "String:" + data);
        }
}

使用UDP建立聊天室

虽然实现了使用UDP进行两个窗口之间的通信,但是要想在一个窗口实现信息的接收与发送需要使用多线程技术。一个线程实现信息的发送,一个线程实现信息的接收。
发送端

public class Send implements Runnable {
    private DatagramSocket socket;
    public Send(DatagramSocket socket) {
        // TODO Auto-generated constructor stub
        this.socket = socket;
    }
    
    @Override
    public void run() {
        // TODO Auto-generated method stub
        try{
            BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
            String line = null;
            while((line = bufr.readLine()) != null){
                if(line.equals("886"))
                    break;
                byte [] buffer = line.getBytes();
                DatagramPacket datap = 
                        new DatagramPacket(buffer, buffer.length, InetAddress.getByName("输入自己的IP地址"), 10002);
                this.socket.send(datap);
            }
        }catch(Exception e){
            throw new RuntimeException("Fail to send.");
        }
    }

}

接收端

public class Receive implements Runnable{
    private DatagramSocket socket;
    public Receive(DatagramSocket socket) {
        // TODO Auto-generated constructor stub
        this.socket = socket;
    }
    
    @Override
    public void run() {
        try{
            while(true){
                byte [] buffer = new byte[1024];
                DatagramPacket datap = new DatagramPacket(buffer, buffer.length);
                this.socket.receive(datap);
                String ip = datap.getAddress().getHostAddress();
                String data = new String(datap.getData(), 0, datap.getLength());
                System.out.println(ip + "::" + data);
            }
        }catch(Exception e){
            throw new RuntimeException("Fail to receive.");
        }
    }
}

主函数

public static void main(String[] args) throws Exception {
        DatagramSocket sendds = new DatagramSocket();
        DatagramSocket receiveds = new DatagramSocket(10002);
        
        new Thread(new Send(sendds)).start();
        new Thread(new Receive(receiveds)).start();
}
上一篇 下一篇

猜你喜欢

热点阅读