我正在嘗試建立一個UDP發送/接收應用程序。我發送一條消息,服務器迴應,然後服務器可以隨時間發送更多信息。我創建了一個線程發送消息,另一個Async線程連續檢查新消息的背景。但是,我沒有正確接收消息。如果我有一個恆定的接收數據包饋送,它工作正常,但當接收數據是隨機的時它不起作用。如何在android的異步函數中持續接收UDP?
例如: 端口1:不斷髮送數據到我的客戶端,所以我每秒都會收到新的數據包。結果很好,我的應用程序顯示每個新的數據包。我的「接收更新」甚至會像「接收」一樣發送。 「Receiving ..」「Receiving ...」
端口2:我隨機接收數據包。只有當我不斷點擊我的發送按鈕時纔會顯示它們。當我按發送按鈕時,我的接收進度點只能迭代。有時候一個小包閃爍並消失。
我想讓端口2工作。我嘗試在發佈進度後將我的inbackground()函數休眠2秒,但這並沒有幫助。我真的很困惑如何使它能夠不斷接收UDP數據包。這是我的代碼。
編輯:現在端口2正確顯示,消息不會閃爍並消失。但是,我的接收...進度點更新確實很慢。我的問題是,在我的「doInBackground」函數中,我有無限的while循環,這個循環不是真的很快執行嗎?所以即使沒有新消息,我仍然會在循環結束時發佈,以便我的「正在接收......」進度點應該向右移動?
編輯再次:我從字面上沒有任何改變的源代碼,只是一些佈局的東西,現在端口2不能再次工作。它不顯示任何新的接收或接收更新欄。
如果我去端口1與恆定的進給,那麼一切都完美地更新...
我試圖尋找其他的問題,無法破譯該怎麼辦。謝謝你的幫助!
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;
}
}
}
}
什麼是您的網絡配置?如果服務器在Internet上,並且Android設備位於NAT後面,則可能會丟失來自服務器的一些數據包,因爲路由器「忘記」了相應的翻譯記錄。爲避免這種情況,設備需要定期向服務器發送數據包以刷新路由器上的NAT轉換記錄。 – vadipp