简体   繁体   中英

Java/Android - Proper way to send and receive data at the same time through a socket

I'm currently working on an android project that is a sort of P2P application (no central server, IP addresses are entered manually). I've already sorted out how two devices are able to connect to each other, but what I seem to be having trouble figuring out is the best way to send data back and forth with a socket.

Right now, I've got two separate threads, one for sending data, and one for receiving data so that neither attempt blocks the other. My receiving thread checks the output stream, looking for an int until one exists. The int is a flag for the type of data being sent, and depending on that flag, the application prepares to grab the rest of the data, it's all predictable.

My problem comes in when trying to set up the sending thread. I was originally going to have it so that a call on the Sender object (an extension of Thread) would simply send the all the data needed, but realized that doing that didn't actually function within the thread.

Instead, I changed it so that the thread constantly runs and checks for a flag that determines the data going to be sent. A function is called from the UI thread, which prepares the data as class members, and then sets the flag, where it is then "picked up" by the thread and sent off to the other device. However, I realized this would take up a really unnecessary amount of processor time since the loop would be checking the flag over and over.

I'm just wondering what the proper way to do this is since android doesn't allow network operations on the UI thread. Would I have to rewrite the Sender object to create a new thread every time it sends a message?

The Sender thread can be halted via wait() . The Thread can be later resumed by sending it a notify() . An short example for the sender would be:

synchronized(this){
  wait();
}


synchronized(sender){
  sender.notify();
}

Edit: Obviously, in the above case "this" and "sender" refer to the same Object (the Sender Thread).

Edit2: Clarification where you need to add those statements. Given your description i assume you have something similiar to the following

public void run(){
  while(alive){
    // synchronized(this){
    if  (getFlags()!=null){
      //send data
      setFlags(null);
    }
    // wait();}
  }
}

in your Sender class. With the synchronized and wait you can keep the Thread from consuming all available cpu resources from a core. Additionally you will need to modify the calling Thread. You will have add the following:

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

Note: If you modify data here that gets accessed in the sender thread you will need to move the synchronized statement further up as this will block the current thread. If the sender blocks too long you might consider queuing the data (eg by having Lists of Objects instead of just Objects) and checking a boolean flag before entering the synchronized block.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM