• 基于UDP用JAVA实现两个进程间的网络通信


    实现是基于UDP协议的的,两个进程(两个java程序)互相发送,并接受各自发送的数据的功能。
    两个包模拟通信的两个进程(人),由于是镜像代码,只贴出一个包中的代码,通信另一方只要做发送端口、ip的修改即可;
    代码顶层设计如下:

    package net.oneperson;
    
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.SocketException;
    import java.net.UnknownHostException;
    
    /*1. 实现基于UDP协议的的,两个进程(两个java程序)互相发送,并接受各自发送的数据的功能。
            (可以参考课堂上edition3非多线程版本或edition4多线程版本实现,都可以哈)
        */
    public class Oneperson {
        //主类应该包含主要配置信息,启动首发线程;
        public static boolean isSenderoff = false;
        public static Object lockClose = new Object();//用来控制访问共享变量isSenderoff的锁
    
    
        public static void main(String args[]) throws SocketException, UnknownHostException {
            DatagramSocket datagramSocket = new DatagramSocket(10086);//定义本人收发端口
    
            ReceiverTask receiverTask = new ReceiverTask(datagramSocket);
            Thread myReceive = new Thread(receiverTask);
            myReceive.start();
    
            String targetIp="127.0.0.1";//对方的Ip,发给本机就是本地ip
            int targetPort = 8888;//对方的端口
            SenderTask senderTask = new SenderTask(datagramSocket,targetIp,targetPort);
            Thread mySend= new Thread(senderTask);
            mySend.start();
    
    
    
        }
    }
    package net.oneperson;
    
    import java.io.IOException;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.SocketException;
    
    public class ReceiverTask implements Runnable {
        private DatagramSocket datagramSocket;
    
        public ReceiverTask(DatagramSocket datagramSocket) {
            this.datagramSocket = datagramSocket;
        }
    
    
        @Override
        public void run() {
            //准备接收数据的package
            byte[] buf = new byte[1024];
            int off = 0;
            DatagramPacket datagramPacket = new DatagramPacket(buf, off, buf.length - off);
            boolean isFinish = false;
    
            //用包装包的接收函数一直接收数据
            try {
                while (true) {
                    isFinish = receiveData(datagramSocket, datagramPacket);
                    if (isFinish) break;//收到再见之前,一直收;收到再见,不再接收,转到finally判断是否可以关闭socket
    
                }
    
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                while (true) {//只要发送方还没说要结束,线程一直在这里空转,等待
                    synchronized (Oneperson.lockClose) {
                        if (Oneperson.isSenderoff) {
                            // datagramSocket.close();//这么写也是可以的
                            break;
                        }
                        try {
                            Oneperson.lockClose.wait(100);//可以在任何对象上调用wait,阻塞的是运行该对象的线程
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
    
                    }
    
    
                }
    
                //可以关闭了
                datagramSocket.close();
            }
        }
    
        /*函数:用于接收数据,并在函数将其内容显示,并判断是否收到886,是的话返回true*/
        private boolean receiveData(DatagramSocket datagramSocket, DatagramPacket receivePacket) throws IOException {
    
            datagramSocket.receive(receivePacket);//接收数据包
    
            byte[] buf = receivePacket.getData();//从数据包获得字节数据
            int off = receivePacket.getOffset();//获得实际收到字节数据的起始位置
            int length = receivePacket.getLength();//本次实际收到数据的长度;
            //解析接收到的字节数据,并将其转化为字符串
            String s = new String(buf, off, length);
            System.out.println(receivePacket.getAddress() + ":" + receivePacket.getPort() + " ," + s);
            if ("886".equals(s)) {
                return true;
            }
            return false;
        }
    
    }
    package net.oneperson;
    
    import java.io.*;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.InetAddress;
    import java.net.UnknownHostException;
    
    public class SenderTask implements Runnable{
        private DatagramSocket socket;
        private static InetAddress targetIp; //要发送的IP地址
        private static int targetPort;//要发送的端口
    
    
    
        //构造方法参数:一个socket,targetID,targetPoet 接口,目标ID,目标端口
        public SenderTask(DatagramSocket socket, String targetIp,int targrtPort) throws UnknownHostException {
            this.targetIp=InetAddress.getByName(targetIp);
            this.targetPort=targrtPort;
            this.socket = socket;
        }
        @Override//执行方法
        public void run() {
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));//因为是健康输入,用System.in;如果是文件,需要一个File路径或目录
            String dataSend;
            while(true){
                try {
                    //发送有输入来,就一直发送
                    if (((dataSend =br.readLine())==null)) break;
                    sendDate(dataSend,socket);
                    if(dataSend.equals("886")){
                        //每次都检查自己是不是发送了886,是的话将标记位标记
                        synchronized (Oneperson.lockClose){
                            Oneperson.isSenderoff = true;
                        }
                        break;
                    }
    
                } catch (IOException e) {
                    e.printStackTrace();
                }
    
            }
    
        }
    
        //SendDate,Q1-为什么要定义成static
        //这个方法是在哪里被使用?run中
        //它要接收参数,发送的信息数据,发送的接口
        private static void sendDate(String data,DatagramSocket datagramSocket) throws IOException {
            byte [] dataBytes = data.getBytes();
            DatagramPacket datagramPacket = new DatagramPacket(dataBytes,0,dataBytes.length,targetIp,targetPort);
            datagramSocket.send(datagramPacket);//send()方法
        }
    }

     运行结果展示:


  • 相关阅读:
    14.3.1选择选项
    14.3 选择框表单
    14.2.4HTML5约束API验证
    input标签之外是否一定添加form标签
    14.2.3自动切换焦点
    php设计模式---抽象模式模式
    php设计模式---简单工厂模式
    git基本教程,每天更新
    第5章 卷积神经网络
    第3章 深度学习基础
  • 原文地址:https://www.cnblogs.com/debug-the-heart/p/13238240.html
Copyright © 2020-2023  润新知