我正在编写一个程序,使用UDP在网络上发送整数(称为intToSend的变量)。我在同一网络的两台计算机上运行该程序,一个接一个。我以为在运行它们两个之后,要运行的第一个将打开带有已发送整数的消息框,但这不会发生。这两个程序都等待接收到一个数据包,如正在打印到控制台的“ Waiting ...”所示。我有程序要求将目标IP输入到控制台。然后,调用createSocket方法,然后依次调用sendData和receiveData。

这是代码:

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;
    }
}

最佳答案

该代码对我有用。如果我输入目标IP作为本地计算机的IP,则会弹出窗口。如果我在网络上输入了另一台计算机,我也会得到弹出窗口。我的猜测是,您的一台计算机运行的防火墙阻止了传入的UDP数据包,或者您的计算机具有多个网络接口,并且您检测到的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.

10-05 23:52
查看更多