【发布时间】:2017-02-03 23:15:28
【问题描述】:
我在 android studio 中制作了一个简单的应用程序来发送 UDP 数据包,所以当我单击一个按钮时,它会调用一个函数来检查哪种类型的组件调用了该函数并分别发送不同的数据包数据。 这是发送数据包的函数:
public void sendPacket(View v) {
if (v instanceof Button)
buffer = ((Button) v).getHint().toString().getBytes();
else if (v instanceof EditText)
buffer = ((EditText) v).getText().toString().getBytes();
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
DatagramPacket packet = new DatagramPacket(buffer, buffer.length, ip, port);
try {
SelectionActivity.datagramSocket.send(packet);
} catch (IOException e) {
e.printStackTrace();
}
}
});
thread.start();
}
这是主函数中调用 sendPacket() 函数的监听器:
btn.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
if (<some checks>)
sendPacket(txt.findViewById(R.id.txt));
sendPacket(btn.findViewById(R.id.btn));
}
});
问题在于它随机发送一个数据和/或另一个即使它改变了。
例如:
1)
缓冲区 = 0x01
发送 0x01
缓冲区 = 0x02
发送 0x02
2)
缓冲区 = 0x01
发送 0x01
缓冲区 = 0x02
发送 0x01
WTF?!
【问题讨论】:
-
您是否在线程中放入了一些
Log.d(或类似的)来记录buffer的状态,以调用SelectionActivity.datagramSocket.send(packet)?如果是,日志是否与问题中显示的日志相同? -
@MargaretBloom 谢谢,我现在有一个更清晰的视图,但我不明白为什么会这样。这是日志的输出(我在它发送预期数据之前点击了几次): D/BUFFER: ZD/BUFFER: ZD/BUFFER: ZD/BUFFER: ZD/BUFFER: ZD/BUFFER: ZD/BUFFER: ZD /BUFFER: ZD/BUFFER: ZD/BUFFER: 2:30 D/BUFFER: ZD/BUFFER: ZD/BUFFER: ZD/BUFFER: ZD/BUFFER: ZD/BUFFER: ZD/BUFFER: ZD/BUFFER: Z(预期数据包是一个接一个的“Z”和“2:30”,但它通常发送“Z”和“Z”,所以它就像根本不改变缓冲区一样,这很奇怪D:)
-
好的,我想问题是线程调用太快了两次,因为如果我在两次调用 sendPacket() 之间休眠,它会按预期工作,有没有更好的解决方案?谢谢
-
简要看一下代码,当将
buffer传递给新线程时,我看不到任何数据竞争,阅读它时也不应该有任何数据竞争。然而send可能不是线程安全的,只是在这里猜测。您可以尝试将对send的调用包装成synchronized (SelectionActivity.datagramSocket) { ... }。
标签: java android sockets android-studio udp