1

I am trying to establish a UDP send/Receive app. I send a message, the server responds back, and then the server MAY send more info over time. I created a thread to send the message, and another Async thread to continuously check in the background for new messages. However, I am not receiving the messages correctly. It works correctly if I have a constant feed of receive packets, but it doesn't work when the receive is random.

For example: Port 1: constantly sends data to my client, so I receive new packets every second. The result is fine, my app shows each and every new packet. My "Receiving update" even ticks to go like "Receiving." "Receiving.." "Receiving..."

Port 2: i receive packets randomly. it shows them only if I keep clicking my send button. My receiving progress dots only iterate when I press the send button. Sometimes a packet flashes and goes away.

I am trying to make port 2 work. I tried putting my inbackground() function to sleep for 2 seconds after I publish a progress, but that didn't help. I am really confused how to make it so I can constantly receive UDP packets. Here is my code.

EDIT: Now port 2 displays correctly, the message doesn't just flash and disappear. However, my Receiving... progress dots update really slow. My question is, in my "doInBackground" function, I have the infinite while loop, doesn't that loop execute constantly really fast? So even if there is no new message, I still publish at the end of the loop so that my "Receiving.." progress dots should move right?

EDIT AGAIN: I literally changed nothing to the source code, just some layout stuff, and now port 2 doesn't work again. It doesn't show any new receives or the receiving update bar.

If I go to port 1 with the constant feed, then everything updates perfectly...

I tried looking at other questions, couldn't decipher what to do. Thanks for your help!

import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.net.SocketException; import java.net.UnknownHostException; import android.os.AsyncTask; import android.os.Bundle; import android.os.StrictMode; import android.provider.Settings.Global; import android.app.Activity; import android.view.Menu; import android.view.View; import android.widget.Button; import android.widget.TextView; public class MainActivity extends Activity { Button button; TextView txt1, txtH, txtE, txtER, txtUpdate; String msg; CharSequence oldMsg="a"; Integer updateCount=0; Activity mActivity; DatagramSocket socket; boolean msgSent = false; boolean errorSend = false; boolean errorReceive = false; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); txt1 = (TextView) findViewById(R.id.textView2); txtH = (TextView) findViewById(R.id.textView1); txtE = (TextView) findViewById(R.id.textView6); txtER = (TextView) findViewById(R.id.textView8); txtUpdate = (TextView) findViewById(R.id.textView9); //I start my async class here new receiveUDP().execute(); button = (Button) findViewById(R.id.button1); //When I click this, I send a message button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Thread sendThread = new Thread(){ public void run(){ try{ byte[] data ="Some MSG".getBytes(); InetAddress address = InetAddress.getByName("Some address"); DatagramPacket pack = null; pack = new DatagramPacket(data,data.length, address, somePort); socket.send(pack); msgSent=true; } catch (Exception e){ boolean errorSend = true; } } }; sendThread.start(); try { sendThread.join(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } if (msgSent){ txtH.setText("SENT!"); } } }); if (errorSend){ txtE.setText("Error Sending Socket"); } } public class receiveUDP extends AsyncTask <Void, CharSequence, Void>{ @Override protected Void doInBackground(Void... params) { //Constantly check to see if we received a new packet. while (true){ try{ //if no socket, create a new socket if (socket == null){ socket = new DatagramSocket(somePort, InetAddress.getByName("address")); socket.setBroadcast(true); } byte[] buf = new byte[2500]; DatagramPacket packet = new DatagramPacket(buf, buf.length); socket.receive(packet); //Get the data of the packet to be a string msg = new String(packet.getData(),0,packet.getLength()); } catch (Exception e){ errorReceive=true; e.printStackTrace(); } publishProgress(msg); } } protected void onProgressUpdate(CharSequence...progress) { updateCount++; // If no errors, and if new message is different than old message // Then change the text field to show new message. if(!(errorReceive)){ if(!(oldMsg.equals(progress[0]))){ txt1.setText(progress[0]); oldMsg = progress[0]; } }else { txtER.setText("Error Receiving"); } //Progress dots... if(updateCount==1){ txtUpdate.setText("Receiving."); } else if(updateCount==2){ txtUpdate.setText("Receiving.."); } else { txtUpdate.setText("Receiving..."); updateCount=0; } } } } 
1
  • What was your network configuration? If the server was on the Internet, and the Android device was behind a NAT, you might lose some packets from server because the router "forgets" the corresponding translation record. To avoid this, the device needs to periodically send packets to the server to refresh the NAT translation record on the router. Commented Nov 8, 2017 at 15:09

1 Answer 1

1

i did it this way with success (consider that my received message is a string using the following symbol to divide parameters |

for this reason you see that i use the split command once message received

p.s.: don't use the emulator, try it on real phone.

p.p.s.: use startReceiveUdp to start listening when you create the activity, then use stopReceiveUdp in your gui thread to stop listening, just before to dismiss your activity (i use it inside onDismiss sub, overriding it).

ReceiveSocket receiveSocket; void startReceiveUdp() { if (receiveSocket==null) { receiveSocket=new ReceiveSocket(); receiveSocket.execute(""); } } void stopReceiveUdp() { if (receiveSocket!=null) receiveSocket.cancel(true); } private class ReceiveSocket extends AsyncTask<String, String, String> { DatagramSocket clientsocket; @Override protected String doInBackground(String... params) { while (true) { try { publishProgress(receiveMessage()); if(isCancelled()) break; } catch (Exception e) { // } } return ""; } String[] receiveMessage(){ String[] rec_arr = null; try { int port = 8081; if (clientsocket == null) clientsocket=new DatagramSocket(port); byte[] receivedata = new byte[30]; DatagramPacket recv_packet = new DatagramPacket(receivedata, receivedata.length); //Log.d("UDP", "S: Receiving..."); clientsocket.receive(recv_packet); String rec_str = new String(recv_packet.getData()); //stringa con mesasggio ricevuto rec_str= rec_str.replace(Character.toString ((char) 0), ""); //Log.d(" Received String ",rec_str); //InetAddress ipaddress = recv_packet.getAddress(); //int port = recv_packet.getPort(); //Log.d("IPAddress : ",ipaddress.toString()); //Log.d(" Port : ",Integer.toString(port)); rec_arr=rec_str.split("\\|"); return rec_arr; } catch (Exception e) { Log.e("UDP", "S: Error", e); } return rec_arr; } @Override protected void onPostExecute(String result) { // } @Override protected void onPreExecute() {} @Override protected void onProgressUpdate(String... rec_arr) { //ricevi la stringa, //splittala //esegui l'azione richiesta sulla GUI if (rec_arr.length>1){ String clientType=rec_arr[0]; String command=rec_arr[1]; if(command.contentEquals("go")){ //press button go startAction(null); } } } } 
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.