用Java发送数据报包

时间:2017-07-27 16:29:16

标签: java networking udp

我正在编写一个程序,使用UDP在网络上发送一个整数(变量名为intToSend)。我在同一个网络上的两台机器上运行程序,一个接一个地运行。我认为在运行它们之后,第一个要运行的将打开一个带有发送整数的消息框,但这不会发生。两个程序都等待接收数据包,如“等待...”所示,打印到控制台。我有程序要求将目标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;
    }
}

1 个答案:

答案 0 :(得分:0)

此代码适用于我。如果我输入目标IP作为本地机器的IP,那么我得到弹出窗口。如果我在网络上输入另一台机器,我也会得到弹出窗口。我的猜测是你的任何一台机器都运行阻止传入UDP数据包的防火墙,或者你的机器有多个网络接口,你检测到的IP不是与另一台机器在同一网络上的IP。 / p>

在前一种情况下,您可以禁用防火墙(如果您的计算机不在具有防火墙的路由器后面或者在您无法完全控制的网络上,则不是一个好主意)或打开特定端口以进行传入和两台机器上的传出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.