用JAVA實現兩個程序間的網路通訊
阿新 • • 發佈:2020-07-05
實現是基於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 = newSenderTask(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()方法 } }
執行結果展示: