Java/Android—通过套接字同时发送和接收数据的正确方式

Java/Android—通过套接字同时发送和接收数据的正确方式,java,android,multithreading,sockets,communication,Java,Android,Multithreading,Sockets,Communication,我目前正在从事一个android项目,这是一种P2P应用程序(没有中央服务器,IP地址是手动输入的)。我已经弄清楚了两个设备是如何相互连接的,但我似乎很难弄清楚的是用套接字来回发送数据的最佳方式 现在,我有两个独立的线程,一个用于发送数据,另一个用于接收数据,这样两个尝试都不会阻止另一个。我的接收线程检查输出流,寻找int,直到一个int存在。int是所发送数据类型的标志,根据该标志,应用程序准备获取其余数据,这一切都是可预测的 我的问题出现在尝试设置发送线程时。我本来打算使用它,这样对发送方对

我目前正在从事一个android项目,这是一种P2P应用程序(没有中央服务器,IP地址是手动输入的)。我已经弄清楚了两个设备是如何相互连接的,但我似乎很难弄清楚的是用套接字来回发送数据的最佳方式

现在,我有两个独立的线程,一个用于发送数据,另一个用于接收数据,这样两个尝试都不会阻止另一个。我的接收线程检查输出流,寻找int,直到一个int存在。int是所发送数据类型的标志,根据该标志,应用程序准备获取其余数据,这一切都是可预测的

我的问题出现在尝试设置发送线程时。我本来打算使用它,这样对发送方对象(线程的扩展)的调用就可以简单地发送所需的所有数据,但我意识到这样做实际上并不能在线程中起作用

相反,我更改了它,使线程不断运行并检查确定要发送的数据的标志。从UI线程调用一个函数,该线程将数据准备为类成员,然后设置标志,然后由线程“拾取”并发送到其他设备。然而,我意识到这会占用处理器大量的时间,因为循环会一遍又一遍地检查标志


我只是想知道做这件事的正确方法是什么,因为android不允许在UI线程上进行网络操作。我是否必须重写发送者对象,以便在每次发送消息时创建一个新线程?

发送者线程可以通过停止。该线程可以在以后通过发送一条消息来恢复。 发送方的一个简短示例是:

synchronized(this){
  wait();
}


synchronized(sender){
  sender.notify();
}
编辑:显然,在上述情况下,“this”和“sender”指的是同一个对象(sender线程)

Edit2:澄清您需要添加这些语句的地方。根据你的描述,我想你有类似的东西

public void run(){
  while(alive){
    // synchronized(this){
    if  (getFlags()!=null){
      //send data
      setFlags(null);
    }
    // wait();}
  }
}
在Sender类中。使用synchronized和wait可以防止线程消耗内核中所有可用的cpu资源。 此外,您还需要修改调用线程。您必须添加以下内容:

public void handleEvents(..) {
  // process the event
  // determine what to send
  // synchronized(sender) {
  sender.setFlags(mydata);
  // sender.notify();}
}

注意:如果在此处修改在发送方线程中访问的数据,则需要将synchronized语句进一步上移,因为这将阻止当前线程。如果发送器块太长,您可能会考虑排队数据(例如,通过对象列表而不是对象列表),并在进入同步块之前检查布尔标志。如果这两个应用程序都是Java和/或Android,那么KryoNet可以减轻你的负担,以简单的方式通过TCP发送数据。Java和Android将以完全不同的方式处理这一问题。在Java中,NIO是您的最佳选择。然而,在Android上,我想你应该创建一个服务。可能会调查并更新您的问题。这是非常广泛的…这以什么方式回答了这个问题?海报不想通过轮询锁定CPU周期。轮询错误,请让发送方线程等待并通知它。这是正确的方法。不是在你参加edt的时候。op需要的与此完全不同。顺便说一下,有一些方法可以完成上述操作,最好是等待/通知。看到“并发”的东西了吗…为什么它是可预分配的?海报已经有了一个有效的解决方案。所需要的只是添加几行。至少他需要一个任务。但如果没有代码,就很难说了。