Ошибка многоадресного сокета Android при получении данных?

Я новичок в программировании сокетов. Я использую Multicast сокет для трансляции через сеть Wi-Fi. Но я сталкиваюсь с проблемой на стороне приемника. Вот мой код на стороне сервера

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;

public class SenderService extends Service
{
SenderThread currentSender;

public class SenderThread extends Thread
{

    public void run()
    {
        Log.d("in thread","in service");
        try
        {
            InetAddress group = InetAddress.getByName("224.0.0.3");
            int port=10000;
            DatagramSocket sock=new DatagramSocket();
            sock.setBroadcast(true);
            String msg="hello";
            byte []b3=new byte[1024];
            DatagramPacket packet;
            b3=msg.getBytes();

            while (true)
            {   
                try
                {
                    packet = new DatagramPacket(b3, b3.length,group, port); 
                    sock.send(packet);
                    Log.d("MSG:", "sent");
                } catch (IOException e)
                {
                    Log.d("Send Excp:", e+"");
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                finally
                {
                    sock.close();
                }
            }

        } catch (Exception e)
        {

            e.printStackTrace();
        }

    }
}
@Override
public void onCreate() {
    // TODO Auto-generated method stub
    super.onCreate();
}

@Override
public IBinder onBind(Intent arg0)
{
    // TODO Auto-generated method stub
    return null;
}

@Override
public int onStartCommand(Intent intent, int flags, int startId)
{
    new SenderThread().start();
    return Service.START_STICKY;
}
}

Код на стороне клиента

 import java.io.IOException;
 import java.net.DatagramPacket;
 import java.net.DatagramSocket;
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
 import java.net.MulticastSocket;
 import java.net.NetworkInterface;
 import java.util.Enumeration;

 import android.app.Activity;
 import android.content.Context;
 import android.net.ConnectivityManager;
 import android.net.NetworkInfo;
 import android.net.wifi.WifiManager;
 import android.net.wifi.WifiManager.MulticastLock;
 import android.os.AsyncTask;
 import android.os.Bundle;
 import android.os.Handler;
 import android.util.Log;
 import android.view.View;
 import android.widget.Button;
 import android.widget.Toast;

 public class ReceiverActivity extends Activity
 {
    Button b;
    Handler h;
    class MyRTh extends Thread
    {
        InetAddress group=null ;
        WifiManager wifi =    (WifiManager)getSystemService(Context.WIFI_SERVICE);
        MulticastLock lock = wifi.createMulticastLock("HelloAndroid");

        public void run()
        {
            try
            {
                lock.acquire();
            }
            catch (Exception e) {
                // TODO: handle exception
                Log.d("lock",e+"");
            }
            try
            {
                final MulticastSocket sock=new MulticastSocket(10000);
                group= InetAddress.getByName("224.0.0.3");
                //sock.setSoTimeout(15000);
                try
                {
                    sock.joinGroup(group);
                }
                catch(Exception e)
                {
                    Log.d("join",""+e.toString());
                }
                while(true)
                {
                try
                {
                    Log.d("in try","l4");
                    byte[] data = new byte[1024]; 

                    // TODO Auto-generated method stub
                    DatagramPacket packet = new DatagramPacket(data, data.length);
                    Log.d("in run","l4");
                    try {
                        sock.receive(packet);
                        String s = new String(packet.getData());
                        Log.e("MSG:", "Received");
                        Log.d("msg",s);
                    } catch (Exception e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                        Log.d("err",e.toString());
                    }
                }
                catch (Exception e)
                {
                    Log.d("Excp", e.toString()+"");
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                }
                }catch (Exception e) {
                // TODO: handle exception
            }
        }
    }

@Override
protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_receiver);
    Toast.makeText(getApplicationContext(), "Receiving", Toast.LENGTH_SHORT).show();
    Log.d("1","l1");

    b=(Button)findViewById(R.id.buttonr);
    b.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View arg0)
        {
            MyRTh th=new MyRTh();
            th.start();
        }
    });
}

}

Моя проблема в том, что мой клиентский код застрял, когда он переходит к методу socket.receive(). Я начал свои мобильные данные с обеих сторон. Запустил Hotspot на стороне сервера и подключился к нему с клиента.

2 ответа

Моя проблема в том, что мой код на стороне клиента зависает при переходе к методу socket.receive()

Это блокирует.

InetAddress group = InetAddress.getByName("224.0.0.3");

Проблема здесь. Адреса многоадресной рассылки в диапазоне от 224.0.0.0 до 224.0.0.255 зарезервированы для низкоуровневых операций многоадресной поддержки. Используйте адрес в диапазоне от 224.0.1.0 до 239.255.255.255, но см. Также RFC 2365.

sock.setBroadcast(true);

Ненужные. Удалить. Вы не вещаете, вы многоадресные.

byte []b3=new byte[1024];
DatagramPacket packet;
b3=msg.getBytes();

Вам не нужно инициализировать b3 когда вы переназначаете его двумя строками позже.

finally
{
    sock.close();
}

Вы закрываете сокет внутри while (true) петля. Таким образом, он отправит одну многоадресную рассылку и затем выйдет с исключением "закрытое гнездо", о котором вы здесь не сообщали. Удалить.

String s = new String(packet.getData());

Которые должны быть new String(packet.getData(), packet.getOffset(), packet.getLength(),

Попытаться установить это включение socket.setBroadcast(true);

    byte[] buf = new byte[256];
    packet = new DatagramPacket(buf, buf.length);
    socket.setBroadcast(true);
    socket.receive(packet);
Другие вопросы по тегам