Java 如何在android的异步函数中使用连续接收UDP?
我正在尝试建立UDP发送/接收应用程序。我发送一条消息,服务器做出响应,然后服务器可能会随时间发送更多信息。我创建了一个线程来发送消息,另一个异步线程在后台连续检查新消息。但是,我没有正确地接收信息。如果我有一个固定的接收数据包馈送,它可以正常工作,但是当接收是随机的时它就不工作了 例如: 端口1:不断向我的客户端发送数据,所以我每秒都会收到新的数据包。结果很好,我的应用程序显示每一个新数据包。我的“接收更新”甚至像“接收”一样滴答作响。“接收…”“接收…” 端口2:我随机接收数据包。只有当我一直点击我的发送按钮时,它才会显示它们。我的接收进度点只有在按下发送按钮时才会重复。有时一个包会闪过,然后消失 我正在努力使端口2正常工作。在发布进度后,我尝试将inbackground()函数休眠2秒钟,但没有效果。我真的很困惑如何使它,所以我可以不断地接收UDP数据包。这是我的密码 编辑:现在端口2正确显示,消息不会闪烁和消失。然而,我的接收。。。进展真的很慢。我的问题是,在我的“doInBackground”函数中,我有一个无限的while循环,这个循环不是一直执行得很快吗?因此,即使没有新消息,我仍然在循环结束时发布,以便我的“接收…”进度点应该向右移动 再次编辑:我没有对源代码做任何修改,只是做了一些布局,现在端口2不再工作了。它不显示任何新接收或接收更新栏 若我使用恒定馈送转到端口1,则所有内容都会完美更新 我试着看其他的问题,不知道该怎么办。谢谢你的帮助Java 如何在android的异步函数中使用连续接收UDP?,java,android,multithreading,asynchronous,udp,Java,Android,Multithreading,Asynchronous,Udp,我正在尝试建立UDP发送/接收应用程序。我发送一条消息,服务器做出响应,然后服务器可能会随时间发送更多信息。我创建了一个线程来发送消息,另一个异步线程在后台连续检查新消息。但是,我没有正确地接收信息。如果我有一个固定的接收数据包馈送,它可以正常工作,但是当接收是随机的时它就不工作了 例如: 端口1:不断向我的客户端发送数据,所以我每秒都会收到新的数据包。结果很好,我的应用程序显示每一个新数据包。我的“接收更新”甚至像“接收”一样滴答作响。“接收…”“接收…” 端口2:我随机接收数据包。只有当我一
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;
}
}
}
}
导入java.net.DatagramPacket;
导入java.net.DatagramSocket;
导入java.net.InetAddress;
导入java.net.SocketException;
导入java.net.UnknownHostException;
导入android.os.AsyncTask;
导入android.os.Bundle;
导入android.os.StrictMode;
导入android.provider.Settings.Global;
导入android.app.Activity;
导入android.view.Menu;
导入android.view.view;
导入android.widget.Button;
导入android.widget.TextView;
公共类MainActivity扩展了活动{
按钮;
TextView txt1、txtH、txtE、txtER、txupdate;
串味精;
CharSequence oldMsg=“a”;
整数updateCount=0;
活动能力;
DatagramSocket套接字;
布尔值msgSent=false;
布尔errorSend=false;
布尔errorReceive=false;
@凌驾
创建时受保护的void(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);
//我在这里开始我的异步类
新建receiveUDP().execute();
按钮=(按钮)findViewById(R.id.button1);
//单击此按钮时,我会发送一条消息
button.setOnClickListener(新视图.OnClickListener(){
@凌驾
公共void onClick(视图v){
线程sendThread=新线程(){
公开募捐{
试一试{
byte[]data=“Some MSG”.getBytes();
InetAddress=InetAddress.getByName(“某个地址”);
DatagramPacket pack=null;
pack=新数据包(data,data.length,address,somePort);
插座。发送(包);
msgSent=true;
}捕获(例外e){
布尔errorSend=true;
}
}
};
sendThread.start();
试一试{
sendThread.join();
}捕捉(中断异常e){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
如果(msgSent){
setText(“已发送!”);
}
}
});
如果(发送错误){
setText(“错误发送套接字”);
}
}
公共类receiveUDP扩展异步任务{
@凌驾
受保护的Void doInBackground(Void…参数){
//不断检查我们是否收到了新的数据包。
while(true){
尝试{//如果没有套接字,请创建一个新的套接字
if(套接字==null){
套接字=新的DatagramSocket(somePort,InetAddress.getByName(“地址”);
插座。路演(真实);
}
字节[]buf=新字节[2500];
DatagramPacket数据包=新的DatagramPacket(buf,buf.长度);
套接字接收(数据包);
//将数据包的数据获取为字符串
msg=新字符串(packet.getData(),0,packet.getLength());
}捕获(例外e){
errorReceive=true;
e、 printStackTrace();
}
出版进度(msg);
}
}
受保护的void onProgressUpdate(CharSequence…progress){
updateCount++;
//如果没有错误,并且新消息与旧消息不同
//然后更改文本字段以显示新消息。
如果(!(错误接收)){
如果(!(oldMsg.equals(进度[0])){
txt1.setText(进度[0]);
oldMsg=进度[0];
}
}否则
{
setext(“错误接收”);
}
//进步点。。。
如果(updateCount==1){
txtUpdate.setText(
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);
}
}
}
}