public class UDPListenerService extends Service {
static String UDP_BROADCAST = "UDPBroadcast";
public static Integer port = 1024; //UDP 초기 포트값
//Boolean shouldListenForUDPBroadcast = false;
DatagramSocket socket; // 데이터 그램 소켓
private void listenAndWaitAndThrowIntent(InetAddress broadcastIP, Integer port) throws Exception {
byte[] recvBuf = new byte[2048];
if (socket == null || socket.isClosed()) {
socket = new DatagramSocket(null);
socket.setReuseAddress(true);
socket.setBroadcast(true);
socket.bind(new InetSocketAddress(broadcastIP,port));
}//소켓이 열리 지않거나 bind 안된경우 소켓 오픈
DatagramPacket packet = new DatagramPacket(recvBuf, recvBuf.length);
Log.e("UDP", "Waiting for UDP broadcast");
socket.receive(packet);
}
}// 수신 IP
Log.e("UDP",""+ MainActivity.trap_add);
//broadcastIntent(senderIP, message);
// socket.close();
}
Thread UDPBroadcastThread;
public void startListenForUDPBroadcast() {
final Handler handler = new Handler();
UDPBroadcastThread = new Thread(new Runnable() {
public void run() {
try {
InetAddress broadcastIP = InetAddress.getByName("0.0.0.0"); //172.16.238.42 //192.168.1.255
while (shouldRestartSocketListen) {
listenAndWaitAndThrowIntent(broadcastIP, port);
handler.post(new Runnable() {
public void run() {
}
});
}
//if (!shouldListenForUDPBroadcast) throw new ThreadDeath();
} catch (Exception e) {
// Toast.makeText(getApplicationContext(),"no longer listening for UDP broadcasts cause of error " + e.getMessage(),Toast.LENGTH_SHORT).show();
Log.i("UDP", "no longer listening for UDP broadcasts cause of error " + e.getMessage());
}
}
});
UDPBroadcastThread.start();
}
private Boolean shouldRestartSocketListen=true;
void stopListen() {
shouldRestartSocketListen = false;
socket.close();
socket.disconnect();
}
@Override
public void onCreate() {
};
@Override
public void onDestroy() {
stopListen();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
shouldRestartSocketListen = true;
startListenForUDPBroadcast();
Log.i("UDP", "Service started");
return START_STICKY;
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
위와 같은 코드를 github에서 가져와 UDP 소켓 통신 실험중입니다.
퍼미션은
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.IN" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.BOOT_COMPLETED" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_SERVICE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permisson android:name="android.permission.READ_EXTERNAL_STORAGE"/>
여러가지 붙여보고 싶은게 많아 이렇게 이용하고 있습니다.
UDP server 오픈시 Waiting for UDP broadcast 가 뜨며 다른 어플리케이션을 이용하여 같은 IP/port로 소켓 오픈시 bind 되어 있다는걸 확인하여 소켓이 제대로 열려 있는 것은 확인했습니다만,
기존에는 제대로 잘 동작 되던 것이 receive에서 멈춰 동작하질 않습니다.
동작환경은 이를 MainActivity 에서
udpListenerService= new UDPListenerService();
udpListenerService.startListenForUDPBroadcast();
다음과 같이 이용하고 있습니다.
play store에 올라와있는 다른 UDP server application을 이용하여 UDP server 를 오픈해서 패킷을 받으려해도 오픈 까지만 진행이 되고 패킷을 받지 못하는데 어떻게 해결해야 할까요? 몇일 고민하다가 이렇게 질문올립니다.
읽어 주셔서 감사합니다.