千家信息网

Java网络编程UDP的实现原理

发表于:2025-01-19 作者:千家信息网编辑
千家信息网最后更新 2025年01月19日,这篇文章主要讲解了"Java网络编程UDP的实现原理",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"Java网络编程UDP的实现原理"吧!UDP实现通信
千家信息网最后更新 2025年01月19日Java网络编程UDP的实现原理

这篇文章主要讲解了"Java网络编程UDP的实现原理",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"Java网络编程UDP的实现原理"吧!

UDP实现通信非常简单,没有服务器,每个都是客户端,每个客户端都需要一个发送端口和一个接收端口。一个客户端向另一个客户端发送消息时,需要知道对方的IP和接收端口,所用到的类为DatagramSocket。

DatagramSocket socket =new DatagramSocket(),发送端socket,若不指定端口,系统自动分配

DatagramSocket socket =new DatagramSocket("接收信息端口"),接收端socket,需要指定接收端口

若想客户端之间进行全双工通信,每个客户端都要有两个线程,一个用于发送信息,一个用于接收信息。

那么UDP怎么实现私聊和群聊呢?(在本机一台电脑的情况下实现)

首先私聊,客户端向另一个客户端发送消息,就要知道其IP(本机都是固定的localhost)和接收端口,也需要姓名进行标识,所以,每个客户端都至少要自己的姓名和接收端口,而且端口不可重复,否则会报端口被占用的错。

其次群聊,由于在本机一台电脑上进行,接收端口各不相同,所以广播就不行了,此时就希望每个客户端在启动的时候,能够把自己的姓名和接收端口给存起来,然后就可以遍历进行群聊。

实现:

  • 第一种,在每个客户端启动时,输入自己的姓名和接收端口,发送信息时,需要输入对方的接收端口号,如果输入时输入了多个端口,就是群发。那么这样每次发送信息时都要指定对方的端口。。。

  • 第二种,客户端启动时,输入姓名和接收端口,此时就把数据存起来,发送信息时,只用指定对方姓名即可。。。可用数据库存,可用文件存,我用的是XML来存。

要创建xml文件,路径在Operation类中

UdpClient.java:

public class UdpClient {        public static void main(String[] args) {                try {                        Scanner scanner = new Scanner(System.in);                        User user = new User();                        System.out.print("请输入用户名》》");                        String userName = scanner.next();                        if (Operation.userIsExist(userName)) {                                //如果此用户已经注册过,直接把注册时用的接收端口分配给他                                user = Operation.findUserByName(userName);                        }else {                                //未注册,用户自己指定端口                                while(true) {                                        System.out.println("请输入接收端口》》");                                        int port = Integer.parseInt(scanner.next());                                        if (Operation.portIsExist(port)) {                                                System.err.println("该端口已被使用,请重新输入。。。。");                                                continue;                                        }else {                                                user.setName(userName);                                                user.setPort(port);                                                Operation.addUser(user);                                                break;                                        }                                }                        }                        new Thread(new SendMsg(user)).start();                        new Thread(new ReceiveMsg(user)).start();                } catch (Exception e) {                        e.printStackTrace();                }        }}

发送信息:

public class SendMsg implements Runnable{        private User self = null;        private DatagramSocket socket = null;        private BufferedReader reader = null;        public SendMsg(User self) {                try {                        socket = new DatagramSocket();                        reader = new BufferedReader(new InputStreamReader(System.in));                        this.self = self;                } catch (Exception e) {                        e.printStackTrace();                }        }        @Override        public void run() {                      try {                        while(true) {                                String[] msg = reader.readLine().split("@");                                if (msg.length != 2) {                                        System.err.println("注意格式:消息@对方名字(私聊)或all(群聊)");                                        continue;                                }                                msg[0] = self.getName()+"说:"+msg[0];                                byte[] data = msg[0].getBytes();                                String toPerson = msg[1];                                if (("all").equals(toPerson)) {                                        //群聊,获取所有用户,不管对方在不在线,都发过去                                        List users = Operation.getUsers();                                        for(User user:users) {                                                if (self != user) {                                                        DatagramPacket packet = new DatagramPacket(data, 0,data.length,new InetSocketAddress("localhost",user.getPort()));                                                    socket.send(packet);                                                }                                        }                                }else {                                        //私聊                                        try {                                                DatagramPacket packet = new DatagramPacket(data, 0,data.length,new InetSocketAddress("localhost",Operation.findUserByName(toPerson).getPort()));                                        socket.send(packet);                                        } catch (Exception e) {                                                System.out.println("对方不在线。。。");                                        }                                }                        }                } catch (Exception e) {                        e.printStackTrace();                }        }}

接收消息:

public class ReceiveMsg implements Runnable{        private DatagramSocket socket = null;        public ReceiveMsg(User user) {                try {                        socket = new DatagramSocket(user.getPort());                } catch (Exception e) {                        e.printStackTrace();                }        }        @Override        public void run() {                try {                        while(true) {                                //准备接收包裹                                byte[] container = new byte[1024];                                DatagramPacket packet = new DatagramPacket(container,0,container.length);                                socket.receive(packet);                                byte[]data = packet.getData();                                String receiveData = new String(data, 0, data.length);                                System.out.println(receiveData);                        }                } catch (Exception e) {                        e.printStackTrace();                }                socket.close();        }}

操作XML文件类:

public class Operation {        private static String FILE_PATH = "config/user.xml";     //文件目录         //在xml文件中添加一个用户信息        public static void addUser(User user)        {                InputStream in = null;                SAXReader reader = new SAXReader();                Document doc = null;                try                {                        in = new FileInputStream(FILE_PATH);                        doc = reader.read(in);                        Element root = doc.getRootElement();   //获取xml根节点,即users节点                        Element element = root.addElement("user");                        element.addElement("name").addText(user.getName());                        element.addElement("port").addText(String.valueOf(user.getPort()));                         FileOutputStream fos = new FileOutputStream(FILE_PATH);                        //格式化xml文件                        OutputFormat format = OutputFormat.createPrettyPrint();                        format.setEncoding("utf-8");                        XMLWriter writer = new XMLWriter(fos,format);                        writer.write(doc);                        writer.close();                }                catch (Exception e)                {                        System.out.println("error");                }                finally                {                        try                        {                                                        if(in != null)                                        in.close();                        }                        catch (IOException e)                        {                                System.out.println("error");                        }                }        }         //列出xml中所有用户信息        public static List getUsers()        {                InputStream in = null;                SAXReader reader = new SAXReader();                Document doc = null;                List users = new ArrayList<>();                try                {                        in = new FileInputStream(FILE_PATH);                        doc = reader.read(in);                        Element root = doc.getRootElement();                        List elements = root.elements();                        for (Element element : elements)                        {                                User user = new User();                                user.setName(element.elementText("name"));                                user.setPort(Integer.valueOf(element.elementText("port")));                                users.add(user);                        }                }                catch (Exception e1)                {                        System.out.println("error");                }                finally                {                        try                        {                                in.close();                        }                        catch (IOException e)                        {                                System.out.println("error");                        }                }                 return users;        }        public static User findUserByName(String name) {                InputStream in = null;                SAXReader reader = new SAXReader();                Document doc = null;                try {                        in = new FileInputStream(FILE_PATH);                        doc = reader.read(in);                        Element root = doc.getRootElement();                        List elements = root.elements();                        for (Element element : elements)                        {                                if(name != null && name.equals(element.elementText("name"))) {                                        User user = new User();                                        user.setName(name);                                        user.setPort(Integer.parseInt(element.elementText("port")));                                        return user;                                }                        }                } catch (FileNotFoundException e) {                        e.printStackTrace();                } catch (DocumentException e) {                        e.printStackTrace();                }                return null;        }                public static boolean portIsExist(int port) {                InputStream in = null;                SAXReader reader = new SAXReader();                Document doc = null;                                try {                        in = new FileInputStream(FILE_PATH);                        doc = reader.read(in);                        Element root = doc.getRootElement();                        List elements = root.elements();                        for (Element element : elements)                        {                                if(port == Integer.parseInt(element.elementText("port")))                                        return true;                        }                                        } catch (FileNotFoundException e) {                        e.printStackTrace();                } catch (DocumentException e) {                        e.printStackTrace();                }                return false;        }        //判断某个用户是否存在该xml中        public static boolean userIsExist(String name)         {                InputStream in = null;                SAXReader reader = new SAXReader();                Document doc = null;                try {                        in = new FileInputStream(FILE_PATH);                        doc = reader.read(in);                        Element root = doc.getRootElement();                        List elements = root.elements();                        for (Element element : elements)                        {                                if(name != null && name.equals(element.elementText("name")))                                        return true;                        }                                        } catch (FileNotFoundException e) {                        e.printStackTrace();                } catch (DocumentException e) {                        e.printStackTrace();                }                return false;        }}

用户实体类:

public class User implements Serializable{        private String name;//姓名        private int port;//接收端口        public String getName() {                return name;        }        public int getPort() {                return port;        }        public void setName(String name) {                this.name = name;        }        public void setPort(int port) {                this.port = port;        }        @Override        public String toString() {                return "User [name=" + name + ", port=" + port + "]";        }        }

运行结果:

感谢各位的阅读,以上就是"Java网络编程UDP的实现原理"的内容了,经过本文的学习后,相信大家对Java网络编程UDP的实现原理这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是,小编将为大家推送更多相关知识点的文章,欢迎关注!

0