簡體   English   中英

用Java發送數據報包

[英]Sending Datagram Packets in Java

我正在編寫一個程序,使用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.

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM