2017-07-27 57 views
0

我正在編寫一個程序,使用UDP通過網絡發送一個整數(名爲intToSend的變量)。我在同一個網絡上的兩臺機器上一個接一個地運行程序。我認爲在運行它們之後,第一個要運行的將打開一個帶有發送整數的消息框,但這不會發生。兩個程序都等待接收數據包,如正在將「Waiting ...」顯示在控制檯上所示。我有程序要求輸入到控制檯的目標ip。之後,調用createSocket方法,接着是sendData,然後是receiveData。發送Java中的數據報包

下面是代碼:

package main; 

import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStreamReader; 
import java.io.PrintStream; 
import java.net.DatagramPacket; 
import java.net.DatagramSocket; 
import java.net.InetAddress; 
import java.net.InetSocketAddress; 
import java.net.SocketException; 
import java.net.URL; 
import java.net.UnknownHostException; 
import java.util.Scanner; 

import javax.swing.JOptionPane; 

public class Main { 

    Scanner s = new Scanner(System.in); 
    PrintStream o = System.out, e = System.err; 

    InetAddress thisAddr, destAddr; 
    DatagramSocket socket; 

    int port = 1729, intToSend = 8; 

    boolean running = true; 

    public static void main(String[] args) { 
     new Main(); 
    } 

    private Main() { 
     try { 
      thisAddr = InetAddress.getLocalHost(); 
      System.out.println("Internal IP: " + thisAddr.getHostAddress().toString()); 
      System.out.println("External IP: " + getIp()); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
     try { 
      destAddr = InetAddress.getByName(getDestIp()); 
     } catch (UnknownHostException e) { 
      e.printStackTrace(); 
     } 

     createSocket(); 
     sendData(); 
     receiveData(); 
    } 

    private void receiveData(){ 
     byte[] receiveBuffer = new byte[1024]; 
     DatagramPacket receivePacket = new DatagramPacket(receiveBuffer, receiveBuffer.length); 
     while(true){ 
      System.out.println("Waiting..."); 
      try { 
       socket.receive(receivePacket); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
      String receivedText = new String(receivePacket.getData()); 
      JOptionPane.showMessageDialog(null, receivedText); 
     } 
    } 

    private void sendData(){ 
     byte[] dataToSend = String.valueOf(intToSend).getBytes(); 
     DatagramPacket packet = new DatagramPacket(dataToSend, dataToSend.length, destAddr, port); 
     try { 
      socket.send(packet); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 

    private void createSocket(){ 
     try { 
      socket = new DatagramSocket(port); 
     } catch (SocketException e) { 
      e.printStackTrace(); 
     } 
    } 


    public static String getIp() throws IOException{ 
     URL whatismyip = new URL("http://icanhazip.com"); 
     BufferedReader in = new BufferedReader(new InputStreamReader(whatismyip.openStream())); 
     return in.readLine(); 
    } 

    private String getDestIp() { 
     String temp; 
     o.println("What is the other user's ip?"); 
     temp = s.nextLine(); 
     return temp; 
    } 
} 
+1

您還未得到足夠的信息。我猜你是在一個線程上運行它,所以receiveData總是在while(true)循環中。 –

+0

@ChristopherSchneider就是這一點。我在計算機1上運行該程序,並將其提供給計算機2的IP地址。然後創建套接字,將數據發送到計算機2,該計算機沒有運行程序,因此沒有偵聽數據包。計算機1然後監聽數據包。然後程序在計算機2上運行。我給它的計算機1的ip,所以它應該發送一個數據包到計算機1,並且它應該在計算機1正在監聽數據包時被接收。 – Matty2532

+0

好的...代碼在哪裏?你已經展示了一些方法,但沒有初始化代碼。 –

回答

0

此代碼對我的作品。如果我輸入目標IP作爲本地機器的IP,那麼我得到彈出窗口。如果我在網絡上輸入另一臺機器,我也會彈出一個窗口。我的猜測是,您的任一臺計算機都有防火牆運行,阻止了傳入的UDP數據包,或者您的計算機有多個網絡接口,並且您檢測到的IP不是與另一臺計算機在同一網絡中的IP。

在前一種情況下,您可以禁用防火牆(如果您的機器不在具有防火牆的路由器後面,或者位於您無法完全控制的網絡上,則不是個好主意),也可以打開特定端口兩臺機器上的傳入和傳出UDP。

在後一種情況下,您希望查看在同一子網上的兩臺機器上顯示的IP(前三個數字在IPv4情況下相同),例如從192.168.1開始。或類似的。

當你得到你的數據包通過你可能會得到一個非常長的彈出窗口,因爲你分配一個1024字節的數組,並把該字符串放在該數組的開始,但然後將整個1024字節數組轉換成一個字符串,可能在你寫入int的前N個字節的末尾包含各種東西。

有解決的各種方法,但是這一點,但一個簡單的方法就可以收拾一組數據到一個數據包,然後讀回可靠的方法是使用ByteArrayInput/OutputStreams和的DataInput/OutputStreams:

//Sending side 
ByteArrayOutputStream bout = new ByteArrayOutputStream(); 
DataOutputStream dout = new DataOutputStream(bout); 
dout.writeInt(N); //this will write 4 bytes 
byte[] packetData = bout.toByteArray(); 

//Receiving side 
byte[] packetBuffer = ...; 
ByteArrayInputStream bin = new ByteArrayInputStream(packetBuffer); 
DataInputStream din = new DataInputStream(bin); 
int N = din.readInt(); //This will read only the first 4 bytes, and use the same marshalling as DataOutputStream to produce a consistent value, even if the integer value is something exceptional like infinity or NaN. 
+0

謝謝,這工作。我忘了在兩臺電腦的Windows防火牆內添加規則。我也有一個虛擬網絡適配器,它在我的一臺計算機上給我提供了錯誤的IP地址。 – Matty2532