Java 网络编程之UDP通信和简单的群聊程序

栏目: Java · 发布时间: 6年前

内容简介:Java 网络编程之UDP通信和简单的群聊程序

UDP通信需要明确的几点:

  1. UDP通信不是面向连接的,发送端不管接收端是否启动是否能接收,发完数据报就结束。
  2. 无论是发送端还是接收端,都需要描述两个对象:套接字和数据报。
  3. 接收端的套接字对象中必须明确接收端口,且必须和发送端指定的目标端口一致。而发送端的套接字中则一般采用随机分配的发送端口。
  4. 无论是发送端还是接收端,数据报中都记录了自己和对方的socket信息(ip+port),还提供了用于发送或接收的数据缓冲区。这些数据只有数据报对象自己最清楚,如 getPort() , getAddress() , getData() 等。
    • (1).只不过对于发送端来说,创建发送报文对象需要指定目标套接字信息(ip+port),还需明确数据发送缓冲区。
    • (2).而对于接收端来说,则只需明确一个数据接收缓冲区即可。
  5. 接收端应该不断循环地负责接收。
  6. UDP套接字类DatagramSocket,UDP数据报类DatagramPacket。

UDPSender端:

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;

public class UDPSender {

    public static void main(String[] args) {
        DatagramSocket dgs = null;
        try {
            // 1. 创建udp发送端的socket,一般使用随机发送端口
            dgs = new DatagramSocket();

            // 2. 创建udp报文包对象
            // 2.1 创建数据发送缓冲区
            String text = "Hello World! I'm coming";
            byte[] buf = text.getBytes();

            // 2.2 创建发送数据报文对象
            InetSocketAddress isa = new InetSocketAddress("192.168.0.124",8888);
            DatagramPacket dgp = new DatagramPacket(buf,buf.length,isa);
            //DatagramPacket dgp = new DatagramPacket(buf, buf.length, InetAddress.getByName("192.168.0.124"), 8888);

            // 3.发送udp报文
            dgs.send(dgp);

        } catch (SocketException e1) {
            e1.printStackTrace();
        } catch (UnknownHostException e2) {
            e2.printStackTrace();
        } catch (IOException e3) {
            e3.printStackTrace();
        } finally {
            // 4. 关闭套接字
            dgs.close();
        }
    }
}

UDPRecver端:

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;

public class UDPRecver {

    public static void main(String[] args) {
        while(true){
            // 1.创建udp接收套接字,接收端必须指定正确的端口
            DatagramSocket dgs = null;
            try {
                dgs = new DatagramSocket(8888);

                // 2. 创建udp接收数据包对象
                byte[] buf = new byte[1024];
                DatagramPacket dgp = new DatagramPacket(buf, buf.length);

                // 3.从套接字中接收数据到数据包中
                dgs.receive(dgp);

                // 4.展示udp发送端相关信息,包括发送的数据
                String data = new String(dgp.getData(), 0, dgp.getLength());
                String ip = dgp.getAddress().getHostAddress();
                int port = dgp.getPort();
                System.out.println("Data: "+data+"   ip: "+ip+"   port: "+port);
            } catch (SocketException s) {
                s.printStackTrace();
            } catch (IOException i) {
                i.printStackTrace();
            } finally {
                dgs.close();
            }
        }
    }
}

UDP实现群聊:

思路:

  1. 一个线程负责发,一个线程负责收,因此使用多线程。
  2. 发送端的数据报目标端应该指定为广播目标。且发送的数据来源于键盘输入。
  3. 接收端要无限循环接收数据,但应该提供下线离开功能。(假设收到了"bye",就表示下线)
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.SocketException;

public class QunChat {
    public static void main(String[] args) throws SocketException {
        //发送端和接收端套接字,接收端套接字端口为8888,需要传递给发送端的报文对象
        DatagramSocket send_socket = new DatagramSocket();
        DatagramSocket recv_socket = new DatagramSocket(8888);

        Sender sender = new Sender(send_socket,8888);
        Recver recver = new Recver(recv_socket);

        Thread send_thread1 = new Thread(sender);
        Thread recv_thread1 = new Thread(recver);
        send_thread1.start();
        recv_thread1.start();
    }
}

class Sender implements Runnable {
    private DatagramSocket send_sock;
    private int dest_port;
    Sender(DatagramSocket s,int port){  //初始化时就指定目标端口
        this.send_sock = s;
        this.dest_port = port;
    }

    public void run() {
        while(true) {
            try {
                //群聊发送目标,以广播为例
                InetSocketAddress isa = new InetSocketAddress("192.168.0.255", dest_port);
                //从键盘接收数据
                BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
                String line;
                while((line=bufr.readLine())!=null) {
                    //如果发送的是bye,则断开,且不发送给接收端
                    if(line.equals("bye")) break;

                    byte[] buf = line.getBytes();
                    DatagramPacket dp = new DatagramPacket(buf,buf.length, isa);
                    send_sock.send(dp);
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                send_sock.close();
            }
        }
    }
}

class Recver implements Runnable {
    private DatagramSocket recv_sock;
    Recver(DatagramSocket socket){
        this.recv_sock = socket;
    }

    public void run() {
        while(true) {
            try {
                //接收报文对象
                byte[] buf = new byte[1024];
                DatagramPacket dp = new DatagramPacket(buf, buf.length);
                recv_sock.receive(dp);
                String src_ip = dp.getAddress().getHostAddress();
                String data = new String(dp.getData(),0,dp.getLength());
                if(data.equals("bye")) System.out.println(src_ip +" leaving");;
                System.out.println("Recviving data: "+ data+" from "+src_ip );
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}

本文永久更新链接地址 http://www.linuxidc.com/Linux/2018-01/150200.htm


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

三位一体

三位一体

[美]迈克尔·马隆 / 黄亚昌 / 浙江人民出版社 / 2015-4 / 98.90

[内容简介] ●本书讲述了罗伯特•诺伊斯、戈登•摩尔和安德鲁•格鲁夫如何缔造了世界上最重要公司的故事。公司的“外交家”诺伊斯被视为圣父、“思想家”摩尔被视为圣灵、“行动家”格鲁夫被视为圣子,这个三位一体的组合创下了企业管理中的奇迹,开创了一个价值万亿美元的产业,将一家初创企业打造成为千亿美元量级的巨型公司。 ●本书作者迈克尔•马隆在接触空前数量的企业档案的基础上,揭示了英特尔公司无处不......一起来看看 《三位一体》 这本书的介绍吧!

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具