PDA

View Full Version : مشکل در دریافت UDP



ehsancompany
یک شنبه 27 آبان 1397, 16:05 عصر
سلام
مشکلی که من دارم اینه که udp میخوام هر 20 میلی ثانیه دیتای که بهش وارد میشه رو بگیره
این کار وقتی دیتا 100ثانیه هست مشکلی نداره
ولی وقتی دیتای که وارد udp میشه رو میگره بعد یه مدت دیگه نمیتونه بگیره
مشکل کار من از کجاس؟؟:اشتباه:



package com.example.ehsancompany.upd_ehsan;


import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;


import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;


public class MainActivity extends AppCompatActivity {


EditText editTextAddress, editTextPort;
Button buttonConnect;
TextView textViewState, textViewRx;


UdpClientHandler udpClientHandler;
UdpClientThread udpClientThread;
private static final String TAG = "MainActivity";


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);


buttonConnect = (Button) findViewById(R.id.connect);
textViewState = (TextView)findViewById(R.id.state);
textViewRx = (TextView)findViewById(R.id.received);


buttonConnect.setOnClickListener(buttonConnectOnCl ickListener);


udpClientHandler = new UdpClientHandler(this);


final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
// udpClientThread = null;
// udpClientThread = new UdpClientThread("192.168.16.254",8080, udpClientHandler);
// udpClientThread.start();
handler.postDelayed(this, 10);
}
}, 10);
}


View.OnClickListener buttonConnectOnClickListener =
new View.OnClickListener() {


@Override
public void onClick(View arg0) {


udpClientThread = new UdpClientThread("192.168.16.254",8080, udpClientHandler);
udpClientThread.start();
buttonConnect.setEnabled(false);
}
};


private void updateState(String state){
textViewState.setText(state);
}


private void updateRxMsg(String rxmsg){
textViewRx.setText(rxmsg);
}




private void clientEnd(){
udpClientThread = null;
textViewState.setText("clientEnd()");
udpClientThread = new UdpClientThread("192.168.16.254",8080, udpClientHandler);
udpClientThread.start();
// buttonConnect.setEnabled(true);


}


public static class UdpClientHandler extends Handler {
public static final int UPDATE_STATE = 0;
public static final int UPDATE_MSG = 1;
public static final int UPDATE_END = 2;
private MainActivity parent;


public UdpClientHandler(MainActivity parent) {
super();
this.parent = parent;
}


@Override
public void handleMessage(Message msg) {


switch (msg.what){
case UPDATE_STATE:
parent.updateState((String)msg.obj);
break;
case UPDATE_MSG:
parent.updateRxMsg((String)msg.obj);
break;
case UPDATE_END:
parent.clientEnd();
break;
default:
super.handleMessage(msg);
}
}
}
public class UdpClientThread extends Thread{


String dstAddress;
int dstPort;
private boolean running;
MainActivity.UdpClientHandler handler;


DatagramSocket socket;
InetAddress address;


public UdpClientThread(String addr, int port, MainActivity.UdpClientHandler handler) {
super();
dstAddress = addr;
dstPort = port;
this.handler = handler;
}


public void setRunning(boolean running){
this.running = running;
}


private void sendState(String state){
handler.sendMessage(
Message.obtain(handler,
MainActivity.UdpClientHandler.UPDATE_STATE, state));
}


@Override
public void run() {
sendState("connecting...");


running = true;


try {
socket = new DatagramSocket();
address = InetAddress.getByName(dstAddress);


// send request
byte[] buf = new byte[256];


DatagramPacket packet = new DatagramPacket(buf, buf.length, address, dstPort);


socket.send(packet);


sendState("connected");


// get response
packet = new DatagramPacket(buf, buf.length);




socket.receive(packet);
String line = new String(packet.getData(), 0, packet.getLength());


handler.sendMessage(
Message.obtain(handler, MainActivity.UdpClientHandler.UPDATE_MSG, line));


} catch (SocketException e) {
e.printStackTrace();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if(socket != null){
socket.close();
handler.sendEmptyMessage(MainActivity.UdpClientHan dler.UPDATE_END);
}
}


}
}


}

rubiks.kde
سه شنبه 29 آبان 1397, 09:34 صبح
خواندن از سوکت باید مدام تکرار بشه ، توی کد شما تنها یه بار کد خونده می شده و بعد تمام میشه . بجای این که هی اتصال رو قطع و وصل کنید یک باز سوکت رو باز کنید ولی در یک تابع while عمل ارسال و دریافت رو تا اخر کار انجام بدید . یه چیزی مثل این مثال :

@Override
protected Void doInBackground(String... strings) {

try {


int count = 0;


String txtIP = strings[0];
int txtPort = Integer.parseInt(strings[1]);


DatagramSocket socket = new DatagramSocket();
socket.setSoTimeout(5000);
isRun = true;
publishProgress("UDP run for " + txtIP + ":" + txtPort);


while (isRun) {


Thread.sleep(300);
count++;


if (count > 6) {
String PING = "PING";
DatagramPacket packet = new DatagramPacket(PING.getBytes(), PING.getBytes().length, InetAddress.getByName(txtIP), txtPort);
socket.send(packet);
publishProgress("send UDP PING");


Thread.sleep(500);


byte[] buffer = new byte[4];
packet = new DatagramPacket(buffer, buffer.length);
socket.receive(packet);
String PONG = new String(packet.getData(), "UTF-8");
publishProgress("receive UDP " + PONG);


count = 0;
}
}


socket.close();


}catch (Exception ex) {
publishProgress("exception in UDP main");
sendLogFile(ex.getMessage());
}
return null;
}

مهدی کرامتی
چهارشنبه 30 آبان 1397, 04:35 صبح
یک مشکل دیگه هم هست. در اندروئید وقتی Lock Screen فعال بشه دریافت بسته های UDP به صورت کلی متوقف میشه. من خیلی دنبال راهکاری برای این مشکل بودم، اما به دلیل محدودیت های فنی و الزامات صرفه جویی در مصرف توان باتری، این مشکل رو نمیشه حل کرد.

rubiks.kde
چهارشنبه 30 آبان 1397, 10:15 صبح
یک مشکل دیگه هم هست. در اندروئید وقتی Lock Screen فعال بشه دریافت بسته های UDP به صورت کلی متوقف میشه. من خیلی دنبال راهکاری برای این مشکل بودم، اما به دلیل محدودیت های فنی و الزامات صرفه جویی در مصرف توان باتری، این مشکل رو نمیشه حل کرد.

بله همین طوره ، من هم چنین مشکلی رو داشتم ولی چون برنامه من تنها روی گوشی های روت شده اجرا می شد با قرار داد مستقیم wake lock برای کرنل مشکل رو حل می کردم ولی مصرف باتری زیاد می شد.

private static final String WAKE_LOCK = "/sys/power/wake_lock";
private static final String WAKE_UNLOCK = "/sys/power/wake_unlock";


protected void wakeLock() {
Shell.SU.run("echo WAKE_LOCK_SUSPEND > " + WAKE_LOCK);
Shell.SU.run("echo main > " + WAKE_LOCK);
Shell.SU.run("echo wlan_rx > " + WAKE_LOCK);
Shell.SU.run("echo WAKE_LOCK_IDLE > " + WAKE_LOCK);


Log.d("IntentService", "start lock");
}


protected void wakeUnlock() {
Shell.SU.run("echo WAKE_LOCK_SUSPEND > " + WAKE_UNLOCK);
Shell.SU.run("echo main > " + WAKE_UNLOCK);
Shell.SU.run("echo wlan_rx > " + WAKE_UNLOCK);
Shell.SU.run("echo WAKE_LOCK_IDLE > " + WAKE_UNLOCK);


Log.d("IntentService", "start unlock");
}