zoukankan      html  css  js  c++  java
  • 基于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()方法
        }
    }

     运行结果展示:


  • 相关阅读:
    149. Max Points on a Line(js)
    148. Sort List(js)
    147. Insertion Sort List(js)
    146. LRU Cache(js)
    145. Binary Tree Postorder Traversal(js)
    144. Binary Tree Preorder Traversal(js)
    143. Reorder List(js)
    142. Linked List Cycle II(js)
    141. Linked List Cycle(js)
    140. Word Break II(js)
  • 原文地址:https://www.cnblogs.com/debug-the-heart/p/13238240.html
Copyright © 2011-2022 走看看