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 دریافت نمی کنم.
شرمنده از طولانی شدن کدها، اما توضیحاتی مختصر در کنار هر کدام هست. امیدوارم بشه کمکم کنید.
در برنامه ای احتیاج دارم تا بسته ای را از فرستنده برای سایرین ارسال و آن ها پس از دریافت به فرستنده پاسخ دهند.
(استفاده از همه پخشی در 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 دریافت نمی کنم.
شرمنده از طولانی شدن کدها، اما توضیحاتی مختصر در کنار هر کدام هست. امیدوارم بشه کمکم کنید.