2017-07-27 54 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