Java利用UDP模式模拟聊天

任务描述

本文主要讲如何实现Java控制台和网络调试工具(以下简称"工具")实现"聊天".
也就是说, Java控制台输入消息, 按回车键盘, 工具上显示消息, 然后工具上发送消息, 控制台打印消息.

注意的是, 这里实现思路存在弊端: 即Java一次只能发送一条消息给工具, 因为Java的发送端以一个线程来运作的, 而这个线程由接收端线程唤醒. 这么做的原因是因为要两个线程要共用一个Java控制台, 避免流冲突.

什么是网络调试工具

上图. 看起来和QQ聊天窗口一样样的.

Paste_Image.png

实现流程图

总的来说, 利用两个线程: 发送端线程接收端线程分别完成发送和接收的任务.

Java利用UDP模式模拟聊天.png

代码

  • main方法代码片
public class demo78 {
    // 2017年9月15日 上午12:19:14  Nisus
    public static void main(String[] args) throws IOException, InterruptedException {
        DatagramSocket socket = new DatagramSocket(6567);  //固定住端口号, 两个线程共用. 注意: 工具上发送消息是根据获取的发送端端口号发送的, 如果接收端不监听一致的端口号, 将不能接受工具发来的消息.
        
        new Thread(new ReceiveMsg(socket)).start(); //开启接收端线程
        Thread.sleep(100); //保证接受端线程先开启
        new Thread(new SendMsg(socket)).start(); //开启发送端线程
                
    }

  • 接收端线程
    /*
     * 接收消息进程
     */
    static class ReceiveMsg implements Runnable {
        
        
        
        private DatagramSocket socket;

        public ReceiveMsg(DatagramSocket socket) {
            super();
            this.socket = socket;
        }

        @Override
        public void run() {
            // 2017年9月15日 上午1:08:54  Nisus
            byte[] buf = new byte[1024];
            DatagramPacket pkt = new DatagramPacket(buf, buf.length);
            while(true) {
                
                    try {
                        
                        socket.receive(pkt);  //等待监听
                        int datalen = pkt.getLength();
                        InetAddress address = pkt.getAddress();
                        byte[] b = pkt.getData();
                        System.out.println(address + ": " + new String(b,0,datalen));
                        
                        
                    }catch(Exception e) {
                        
                    }
                    
                    
                    //到这里说明发送端发送数据了, 且wait()了
                    synchronized ("") {
                        "".notify();
                    }
                
                
                
            }
            
            
            
            
        }
        
        
        
        
    }
    

  • 发送端线程
    /*
     * 发送消息进程
     */
    static class SendMsg implements Runnable{

        private DatagramSocket socket;

        public SendMsg(DatagramSocket socket) {
            super();
            this.socket = socket;
        }

        @Override
        public void run() {
            // 2017年9月15日 上午12:59:53  Nisus
            Scanner sc = new Scanner(System.in);
            while(true) {
                synchronized ("") {
                            
                    try {   
    
                        String sender = sc.nextLine();
                        byte[] buf = sender.getBytes("gbk");
                        DatagramPacket pkt = new DatagramPacket(buf, buf.length, InetAddress.getByName("192.168.117.22"), 8888);  //绑定工具IP和端口号, 这里IP就是本机IP, 端口号在工具上手动设置成了8888

                        socket.send(pkt);
                        
                        
                        "".wait();  //发送完后等待
                        
//                      Thread.sleep(5000);
                        
                    }catch(Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    
}

效果图

Paste_Image.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容