PDA

View Full Version : Udp Broadcast packets



suraty
سه شنبه 26 خرداد 1394, 12:48 عصر
سلام،
در برنامه ای احتیاج دارم تا بسته ای را از فرستنده برای سایرین ارسال و آن ها پس از دریافت به فرستنده پاسخ دهند.
(استفاده از همه پخشی در Udp protocol )

کلاس Discoverer.java:


public class Discoverer extends Thread {

private static final String TAG = "Discovery";
private static final int DISCOVERY_PORT = 2562;
private static final int TIMEOUT_MS = 15000;

private WifiManager mWifi;

interface DiscoveryReceiver {
void addAnnouncedServers(InetAddress[] host, int port[]);
}

Discoverer(WifiManager wifi) {
mWifi = wifi;
}

public void run() {
try {
DatagramSocket socket = new DatagramSocket(DISCOVERY_PORT);
socket.setBroadcast(true);
socket.setSoTimeout(TIMEOUT_MS);
sendDiscoveryRequest(socket);
listenForResponses(socket);
} catch (IOException e) {
Log.e(TAG, "Could not send discovery request", e);
}
}

//Send a broadcast UDP packet

private void sendDiscoveryRequest(DatagramSocket socket) throws IOException {
String data = "my data";
Log.d(TAG, "Sending data " + data);
DatagramPacket packet = new DatagramPacket(data.getBytes(),
data.length(), InetAddress.getByName("127.0.0.1") // 'Within' the emulator!/*getBroadcastAddress()*/
, DISCOVERY_PORT);
socket.send(packet);
}

// Calculate the broadcast IP we need to send the packet along.
private InetAddress getBroadcastAddress() throws IOException {
DhcpInfo dhcp = mWifi.getDhcpInfo();
if (dhcp == null) {
Log.d(TAG, "Could not get dhcp info");
return null;
}
int broadcast = (dhcp.ipAddress & dhcp.netmask) | ~dhcp.netmask;
byte[] quads = new byte[4];
for (int k = 0; k < 4; k++)
quads[k] = (byte) ((broadcast >> k * 8) & 0xFF);
return InetAddress.getByAddress(quads);
}

// Listen on socket for responses, timing out after TIMEOUT_MS

private void listenForResponses(DatagramSocket socket) throws IOException {
byte[] buf = new byte[1024];
try {

while (true) {
DatagramPacket packet = new DatagramPacket(buf, buf.length);
socket.receive(packet);
String s = new String(packet.getData(), 0, packet.getLength());

Log.d(TAG, "Received response " + s);
}
} catch (SocketTimeoutException e) {
Log.d(TAG, "Receive timed out");
}
}


}



کلاس Rec_broadcast.java:



public class Rec_Broadcast extends AsyncTask<Void, Void, Void> {

@Override
protected Void doInBackground(Void... urls)
{
DatagramSocket socketUDP;

try
{
socketUDP = new DatagramSocket(5050,InetAddress.getByName("127.0.0.1"));
socketUDP.setSoTimeout(85000);

// set it to true if you want to receive broadcast packets
socketUDP.setBroadcast(false);
}
catch (Exception e)
{
e.printStackTrace();
return null;
}

byte[] buff = new byte[512];
DatagramPacket packet = new DatagramPacket(buff, buff.length);
boolean asyncTask_UDP_is_running;
try
{
asyncTask_UDP_is_running=true;
boolean aplicationActive = true;
// Keep running until application gets inactive
while (aplicationActive)
{
Log.i("my client","Ready to receive broadcast packets!");
try
{
socketUDP.receive(packet);
Log.i("my client", "Packet received from: " + packet.getAddress().getHostAddress());
String data = new String(packet.getData()).trim();
Log.i("my client", "Packet received data: " + data);
}
catch (java.net.SocketTimeoutException ex)
{
// timeout
}
catch (Exception e)
{
Log.i("my client", "Oops" + e.getMessage());
return null;
}
}
}
finally
{
asyncTask_UDP_is_running=false;
}
return null;
}
}


MainActivity:



WifiManager w = (WifiManager) getSystemService(Context.WIFI_SERVICE);
new Rec_Broadcast().execute();
new Discoverer(w).start();



Manifest:


<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/><uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE"/>
<uses-permission android:name="android.permission.INTERNET"/>


اما در Logcat پیامی مبنی بر دریافت داده توسط کلاس Rec_Broadcast دریافت نمی کنم.
شرمنده از طولانی شدن کدها، اما توضیحاتی مختصر در کنار هر کدام هست. امیدوارم بشه کمکم کنید.

tux-world
سه شنبه 26 خرداد 1394, 14:02 عصر
ببین دوست عزیز تو AsuncTask. شما وقتی که دارید از doBackground استفاده میکنید بهتره از یه لیسنر استفاده کنید خروجی رو به بیرون پاس بدید. اسینک اینکار رو نمیکنه. شما تو متدت نمیبینم اینا رو

@Override
protected void onPostExecute(String result) {
}

@Override
protected void onPreExecute() {
}

@Override
protected void onProgressUpdate(Void... values) {
}

یا میتونی خروجی رو بدی به onPostExecute و از طریق اون خروجی رو به بیرون منتقل کنی ولی عاقلانش و صحیحش اینه از یه interface استفاده کنی و گوش به زنگ باشی :لبخندساده:

suraty
چهارشنبه 27 خرداد 1394, 11:22 صبح
مشکل اینجاست که اصلا پیغام های ساده ای که نوشتم رو در LogCat نمی بینم. یعنی اینا رو:


socketUDP.receive(packet);
Log.i("my client", "Packet received from: " + packet.getAddress().getHostAddress());
String data = new String(packet.getData()).trim();
Log.i("my client", "Packet received data: " + data);




نمی دونم اشکال از کجاست؟؟؟
شما هم این کدها رو تست کردید؟ جواب نداده؟؟