Java UDP 套接字回显字节
Java UDP socket echoing bytes
我正在编写一个 android 源代码(但只是 java)来与一些充当服务器的嵌入式设备进行通信。
我确定我的 UDP 数据报已到达设备,因为我可以观察到设备状态的变化。
但问题是我无法从服务器获得响应。没有收到任何东西,但我只是收到了我发送的内容的回声。我的来源如下。
public void sendSnapShot(View view) {
//send a udp datagram to the server.
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... voids) {
try {
Log.e("Test", "send sendSnapShot onLine");
DatagramSocket clientSocket = new DatagramSocket();
byte[] sendData = new byte[1024];
String sentence = "$SNAPSHOT";
sendData = sentence.getBytes();
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, InetAddress.getByName("192.168.5.255"), 9999);
clientSocket.send(sendPacket);
Log.e("Test", "Sent sendSnapShot REQUEST");
} catch (Exception e) {
Log.e("Test", "e", e);
}
return null;
}
}.execute();
}
以上代码是向服务器传输数据报。在应用程序启动时,将启动以下线程以侦听服务器发送的任何数据报。
private class ListenerThread implements Runnable {
//listen for incoming datagrams.
@Override
public void run() {
DatagramSocket serverSocket = null;
try {
InetAddress serverAddr = InetAddress.getByName("192.168.5.255");
serverSocket = new DatagramSocket(9999, serverAddr);
while (true) {
try {
byte[] receiveData = new byte[1024];
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
serverSocket.receive(receivePacket);
receivePacket.getLength();
String receivedData = new String(receivePacket.getData(), 0, receivePacket.getLength());
if (!receivedData.startsWith("!HEARTBEAT")) {
Log.e("Test", "Received : " + receivedData);
} else {
Log.e("Test", "Received : HEARTBEAT");
}
} catch (Exception e) {
Log.e("Test", "FROM SERVER ", e);
}
}
} catch (Exception e) {
Log.e("Test", "Exception", e);
}
}
}
写服务器代码的人(可能是用c++写的)说他在他的测试用例中得到了响应,那么我可能遗漏了什么?上面的代码是否有可能忽略来自服务器的任何数据报和从我的代码发送的回显字节?
============================================= ================================
我已经根据答案更改了我的代码。我不再使用监听线程了。这是我的代码。
public void sendBattery(View view) {
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... voids) {
try {
Log.e("Test", "send Battery onLine");
DatagramSocket clientSocket = new DatagramSocket(9999, InetAddress.getByName("0.0.0.0"));
byte[] sendData = new byte[1024];
byte[] receivedata = new byte[1024];
String sentence = "$S0B255";
DatagramPacket receivePacket = new DatagramPacket(receivedata, receivedata.length);
sendData = sentence.getBytes();
String receivedData = " ";
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, InetAddress.getByName("192.168.5.1"), 9999);
clientSocket.send(sendPacket);
do{
clientSocket.receive(receivePacket);
receivedData = new String(receivePacket.getData(), 0, receivePacket.getLength());
Log.e("Test", receivedData + ", IP CHECK Sender: : " + receivePacket.getAddress().toString() + ", port : "+ receivePacket.getPort());
}while(true);
// Log.e("Test", "Sent BATTERY REQUEST COMPL");
} catch (Exception e) {
Log.e("Test", "e", e);
}
return null;
}
}.execute();
}
根据我收到的心跳字节(使其成为字符串将使其成为“!HEARTBEAT”),发件人是192.168.5.1。但是,我仍然只得到心跳字节。我会错过什么?
- 您正在接收自己的数据报,因为您正在广播(至 192.168.5.255)。您应该使用设备的实际 IP 地址。
- 您不应在每次发送时创建新的数据报套接字。 (你永远不会关闭那个套接字,所以你也在泄漏套接字。)
- 您应该从接收数据的同一个套接字发送数据报。该设备将(应该)回复请求来自的 IP:port,目前每次都不一样,您正在丢失绑定到该端口的发送套接字,而发送 IP:port 是不是您正在收听的IP:port,所以您听不到。
- 您不应将侦听套接字绑定到特定的 IP 地址,当然也不应绑定到广播地址。我很惊讶它的效果。
EJP 所说的一切都是正确的。
上面的固定代码(最下面的代码片段)包含他的提示可以工作,而无需我自己接收任何广播。
我认为问题没有解决,因为我仍然没有收到设备的任何响应,但故障是设备(不是我制造的)。上面的代码会很好用。
我正在编写一个 android 源代码(但只是 java)来与一些充当服务器的嵌入式设备进行通信。
我确定我的 UDP 数据报已到达设备,因为我可以观察到设备状态的变化。
但问题是我无法从服务器获得响应。没有收到任何东西,但我只是收到了我发送的内容的回声。我的来源如下。
public void sendSnapShot(View view) {
//send a udp datagram to the server.
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... voids) {
try {
Log.e("Test", "send sendSnapShot onLine");
DatagramSocket clientSocket = new DatagramSocket();
byte[] sendData = new byte[1024];
String sentence = "$SNAPSHOT";
sendData = sentence.getBytes();
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, InetAddress.getByName("192.168.5.255"), 9999);
clientSocket.send(sendPacket);
Log.e("Test", "Sent sendSnapShot REQUEST");
} catch (Exception e) {
Log.e("Test", "e", e);
}
return null;
}
}.execute();
}
以上代码是向服务器传输数据报。在应用程序启动时,将启动以下线程以侦听服务器发送的任何数据报。
private class ListenerThread implements Runnable {
//listen for incoming datagrams.
@Override
public void run() {
DatagramSocket serverSocket = null;
try {
InetAddress serverAddr = InetAddress.getByName("192.168.5.255");
serverSocket = new DatagramSocket(9999, serverAddr);
while (true) {
try {
byte[] receiveData = new byte[1024];
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
serverSocket.receive(receivePacket);
receivePacket.getLength();
String receivedData = new String(receivePacket.getData(), 0, receivePacket.getLength());
if (!receivedData.startsWith("!HEARTBEAT")) {
Log.e("Test", "Received : " + receivedData);
} else {
Log.e("Test", "Received : HEARTBEAT");
}
} catch (Exception e) {
Log.e("Test", "FROM SERVER ", e);
}
}
} catch (Exception e) {
Log.e("Test", "Exception", e);
}
}
}
写服务器代码的人(可能是用c++写的)说他在他的测试用例中得到了响应,那么我可能遗漏了什么?上面的代码是否有可能忽略来自服务器的任何数据报和从我的代码发送的回显字节?
============================================= ================================
我已经根据答案更改了我的代码。我不再使用监听线程了。这是我的代码。
public void sendBattery(View view) {
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... voids) {
try {
Log.e("Test", "send Battery onLine");
DatagramSocket clientSocket = new DatagramSocket(9999, InetAddress.getByName("0.0.0.0"));
byte[] sendData = new byte[1024];
byte[] receivedata = new byte[1024];
String sentence = "$S0B255";
DatagramPacket receivePacket = new DatagramPacket(receivedata, receivedata.length);
sendData = sentence.getBytes();
String receivedData = " ";
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, InetAddress.getByName("192.168.5.1"), 9999);
clientSocket.send(sendPacket);
do{
clientSocket.receive(receivePacket);
receivedData = new String(receivePacket.getData(), 0, receivePacket.getLength());
Log.e("Test", receivedData + ", IP CHECK Sender: : " + receivePacket.getAddress().toString() + ", port : "+ receivePacket.getPort());
}while(true);
// Log.e("Test", "Sent BATTERY REQUEST COMPL");
} catch (Exception e) {
Log.e("Test", "e", e);
}
return null;
}
}.execute();
}
根据我收到的心跳字节(使其成为字符串将使其成为“!HEARTBEAT”),发件人是192.168.5.1。但是,我仍然只得到心跳字节。我会错过什么?
- 您正在接收自己的数据报,因为您正在广播(至 192.168.5.255)。您应该使用设备的实际 IP 地址。
- 您不应在每次发送时创建新的数据报套接字。 (你永远不会关闭那个套接字,所以你也在泄漏套接字。)
- 您应该从接收数据的同一个套接字发送数据报。该设备将(应该)回复请求来自的 IP:port,目前每次都不一样,您正在丢失绑定到该端口的发送套接字,而发送 IP:port 是不是您正在收听的IP:port,所以您听不到。
- 您不应将侦听套接字绑定到特定的 IP 地址,当然也不应绑定到广播地址。我很惊讶它的效果。
EJP 所说的一切都是正确的。
上面的固定代码(最下面的代码片段)包含他的提示可以工作,而无需我自己接收任何广播。
我认为问题没有解决,因为我仍然没有收到设备的任何响应,但故障是设备(不是我制造的)。上面的代码会很好用。