![](/img/trans.png)
[英]Unable to receive UDP data on Android from PC server over the Internet
[英]Unable to receive datagram over the internet
我有一个UDP客户端向我的UDP服务器发送数据包。
当我使用服务器的IP地址或使用路由器的公用IP地址时,成功发送和接收数据包
// Works
Constants.SERVER_IP_ADDRESS
// Works
Constants.PUBLIC_IP_ADDRESS;
但是,即使设置了转发功能,通过Internet发送时也无法接收任何数据包。
知道为什么吗? 谢谢。
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();
}
}
注意事项:
RuntimeException
可能是不必要的...有关NPE,请参见上文。 run()
方法中处理异常的另一种方法是使用默认的异常处理程序。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.