基于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()方法
    }
}

 运行结果展示:


原文地址:https://www.cnblogs.com/debug-the-heart/p/13238240.html