gpt4 book ai didi

java - 无法通过互联网接收数据报

转载 作者:行者123 更新时间:2023-12-02 12:21:12 24 4
gpt4 key购买 nike

我有一个 UDP 客户端向我的 UDP 服务器发送数据包。

使用服务器IP地址或使用路由器公网IP地址时均发送和接收成功

// Works
Constants.SERVER_IP_ADDRESS

// Works
Constants.PUBLIC_IP_ADDRESS;

但是,即使我设置了转发,通过互联网发送时我也无法收到任何数据包。

知道为什么吗?谢谢。

UdpClient

public class UdpClient {

private String mServerAddress = Constants.PUBLIC_IP_ADDRESS;
private int mServerPort = Constants.PORT;
private static final int MAX_TRIES = 5;

public void sendDatagramPacket(){

// Cannot network on Main UI thread
new AsyncTask(){
@Override
protected Object doInBackground(Object[] objects) {

System.out.println("sendDatagramPacket");

// Create a socket
DatagramSocket socket = null;
try{socket = new DatagramSocket();}
catch (SocketException e){e.printStackTrace();}

// Create a datagram
byte[] bytesToSend = new byte[3];
bytesToSend[0] = (byte) 255;
bytesToSend[1] = (byte) 255;
bytesToSend[2] = (byte) 255;

InetAddress serverInetAddress = null;
try{serverInetAddress = InetAddress.getByName(mServerAddress);}
catch (UnknownHostException e) {e.printStackTrace();}

DatagramPacket datagramPacket = new DatagramPacket(
bytesToSend, bytesToSend.length, serverInetAddress, mServerPort);

// Send packet; packets may be lost, so we have to keep trying
int tries = 0;
while(tries < MAX_TRIES) {
try{socket.send(datagramPacket);}
catch (NullPointerException e){e.printStackTrace();}
catch (IOException e){e.printStackTrace();}
tries++;
}

try{socket.close();}
catch (NullPointerException e){e.printStackTrace();}

return null;
}
}.execute();
}
}

UdpServer

public class UdpServer {

private int mHostPort = Constants.MAC_PORT;

// Defines max receive-buffer size; maximum possible for UDP is ~64,000
private static final int MAX_BUFFER_SIZE = 256;

public void listenForPacket(){

System.out.println("listenForPacket");

new Thread(){
@Override
public void run(){

// Get the socket to the receiving port
DatagramSocket socket = null;
try { socket = new DatagramSocket(mHostPort);}
catch (SocketException e){e.printStackTrace();}

// Create receive-buffer and receive-packet
byte[] receiveBuffer = new byte[MAX_BUFFER_SIZE];
DatagramPacket datagramPacket = new DatagramPacket(receiveBuffer,MAX_BUFFER_SIZE);

// Pause thread here listening for packet
try{
socket.receive(datagramPacket);
System.out.println("Datagram received successfully");
}
catch (IOException e){e.printStackTrace();}



try{socket.close();}
catch (NullPointerException e){e.printStackTrace();}
}
}.start();
}
}

最佳答案

此答案并不能直接解决您的问题,但它可以间接解决您的问题。 (您糟糕的异常处理可能隐藏其他问题......)

您处理异常的方式存在系统性问题。例如:

    DatagramSocket socket = null;
try { socket = new DatagramSocket(mHostPort);}
catch (SocketException e){e.printStackTrace();}

如果构造函数抛出异常会发生什么?

答案:打印堆栈跟踪,然后继续前进,就好像没有发生任何不好的事情一样。

除非发生了一些不好的事情。事实上,如果构造函数失败,并且您没有 DatagramSocket,那么其余代码可能无法工作。但你“康复了”。

这种模式在很多地方重复出现。事实上,您最终会得到捕获由不正确的“恢复”代码直接引起的NPE的代码。

这是正确的方法:

public void run() {
try (DatagramSocket socket = new DatagramSocket(mHostPort)) {

// Get the socket to the receiving port
DatagramSocket socket = new DatagramSocket(mHostPort);

// Create receive-buffer and receive-packet
byte[] receiveBuffer = new byte[MAX_BUFFER_SIZE];
DatagramPacket datagramPacket =
new DatagramPacket(receiveBuffer,MAX_BUFFER_SIZE);

// Pause thread here listening for packet
socket.receive(datagramPacket);
System.out.println("Datagram received successfully");
}
catch (IOException | RuntimeException e) {
e.printStackTrace();
}
}

注意事项:

  • 除了更正确(我声称)之外,此代码实际上比您的版本更简单。错误案例减少了,而且(我声称)那些讨厌的 NPE 的来源已经被消除了。
  • 异常处理不会尝试恢复。如果发生异常,线程将立即结束...
  • 请注意使用 try-with-resources 来确保套接字始终关闭。
  • 捕获 RuntimeException 可能是不必要的......请参阅上面有关 NPE 的内容。
  • run() 方法中处理异常的另一种方法是使用默认异常处理程序。

关于java - 无法通过互联网接收数据报,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45765911/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com