Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java android和UDP数据包的奇怪行为_Java_Android_Sockets_Android Studio_Udp - Fatal编程技术网

Java android和UDP数据包的奇怪行为

Java android和UDP数据包的奇怪行为,java,android,sockets,android-studio,udp,Java,Android,Sockets,Android Studio,Udp,我在android studio中制作了一个简单的应用程序来发送UDP数据包,所以当我点击一个按钮时,它会调用一个函数来检查哪种类型的组件调用了该函数,并分别发送不同数据包的数据。 以下是发送数据包的函数: public void sendPacket(View v) { if (v instanceof Button) buffer = ((Button) v).getHint().toString().getBytes(); else if (v in

我在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));
        }
    });
btn.setOnClickListener(新视图.OnClickListener(){
公共void onClick(视图v){
如果()
sendPacket(txt.findviewbyd(R.id.txt));
sendPacket(btn.findviewbyd(R.id.btn));
}
});
问题在于,即使数据发生变化,它也会随机发送一个和/或另一个数据

例如:

(一)

缓冲区=0x01

发送0x01

缓冲区=0x02

发送0x02

(二)

缓冲区=0x01

发送0x01

缓冲区=0x02

发送0x01


WTF

使用
thread.join()
解决,因为它需要等待线程完成,然后再发送带有更新缓冲区的新数据包。

使用
thread.join()
解决,因为它需要等待线程完成,然后再发送带有更新缓冲区的新数据包。

您是否放置了一些
Log.d
(或类似)在线程中,通过调用
选择活动.datagramSocket.send(packet)
来记录
缓冲区的状态。如果是,日志是否与问题中显示的日志相同?@MargaretBloom谢谢,我现在有了更清晰的视图,但我不明白为什么会发生这种情况。这是日志的输出(在发送预期数据之前,我单击了几次):D/BUFFER:zd/BUFFER:zd/BUFFER:zd/BUFFER:zd/BUFFER:zd/BUFFER:zd/BUFFER:zd/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){…}
。在调用
SelectionActivity.datagramSocket.send(数据包)时,您是否在线程中放置了一些
Log.d
(或类似)来记录
缓冲区的状态
?如果是,日志是否与问题中显示的日志相同?@MargaretBloom谢谢,我现在有了一个更清晰的视图,但我不明白为什么会发生这种情况。这是日志的输出(在发送预期数据之前,我单击了几次):D/BUFFER:zd/BUFFER:zd/BUFFER:zd/BUFFER:zd/BUFFER:zd/BUFFER:zd/BUFFER:2:30d/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
的调用包装成
代码>已同步(SelectionActivity.datagramSocket){…}
。请使用更多信息进行编辑。不鼓励使用“仅代码”和“尝试此”回答,因为它们不包含可搜索的内容,并且不解释为什么有人应该“尝试此”。@abarisone好的,我将使用更多信息进行编辑。仅使用代码和“尝试此”答案是不鼓励的,因为它们不包含可搜索的内容,也没有解释为什么有人应该“尝试这个”。@abarisone好的,我会的