Reputation: 7018
I have an app which works with UDP packets. So I want to send and receive UDP packets at the same time in the same app. Is it real? Now it works perfectly, but separately.
Code snippet:
UDP Server:
public class UDPServer {
DatagramPacket packet;
DatagramSocket socket;
static int port = 11111;
private boolean isRun = false;
private String message = "";
private int broadcastInterval;
private Context context;
public boolean IsRunUDPServer(){
return isRun;
}
public void StopBroadcasting(){
isRun = false;
}
public void StartBroadcasting(String message, int broadcastInterval){
isRun = true;
this.message = message;
this.broadcastInterval = broadcastInterval;
new Thread(runner).start();
}
Runnable runner = new Runnable() {
public void run() {
while(isRun){
try {
//Sending(message);
SendBroadcastMessageOverWiFi(message);
Thread.sleep(broadcastInterval);
Log.e("SendBroadcastMessageOverWiFi", message);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (IOException e) {
}
}
if(socket!=null){
socket.disconnect();
socket.close();
}
}
};
public UDPServer(Context context) {
this.context=context;
}
private InetAddress getBroadcastAddress() throws IOException {
WifiManager wifi = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
DhcpInfo dhcp = wifi.getDhcpInfo();
// handle null somehow
if(dhcp==null){ 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);
}
private void SendBroadcastMessageOverWiFi(String message) throws IOException{
InetAddress addr = getBroadcastAddress();
if(addr!=null){
if(socket==null){
socket = new DatagramSocket(port);
socket.setBroadcast(true);
}
DatagramPacket packet = new DatagramPacket(message.getBytes(), message.getBytes().length,
addr, port);
socket.send(packet);
}
}}
UDP Client:
public class UDPClient {
MulticastSocket socket;
InetAddress groupAddress;
DatagramPacket packet;
byte[] buffer;
private static final int UDP_SERVER_PORT = 11111;
private static final int MAX_UDP_DATAGRAM_LEN = 32768;
public interface OnReceiveDataListener{
public abstract void onReceiveData(String data);
}
private OnReceiveDataListener ReceiveDataListener = null;
public void setReceiveDataListener(OnReceiveDataListener ReceiveDataListener) {
this.ReceiveDataListener = ReceiveDataListener;
}
public OnReceiveDataListener getReceiveDataListener() {
return ReceiveDataListener;
}
private boolean isRun = false;
private Thread broadcastReceiver;
public void StopReceiving(){
isRun = false;
}
public void StartReceiving(){
isRun = true;
buffer = new byte[4096];
broadcastReceiver = new Thread(runner);
broadcastReceiver.start();
}
Runnable runner = new Runnable() {
@Override
public void run() {
while(isRun){
String lText;
packet = new DatagramPacket(buffer, buffer.length);
DatagramSocket ds = null;
try {
ds = new DatagramSocket(UDP_SERVER_PORT);
ds.receive(packet);
lText = new String(packet.getData(), 0, packet.getLength());
Log.i("UDP packet received", lText+" "+packet.getLength()+" "+packet.getData().length);
if(getReceiveDataListener()!=null)
getReceiveDataListener().onReceiveData(lText);
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (ds != null) {
ds.close();
}
}
}
}
};}
If I start server, the client won't be able receive udp packets. Please help me. Thank you.
Upvotes: 1
Views: 4971
Reputation: 3303
Only one socket (in one process) can bind to a given UDP port at one time. It is not permitted to have two sockets bind to the same UDP port number.
In most cases, there is no reason to have the client bound to a specific port. Instead, specify port 0
(INADDR_ANY
) and the system will assign an unused dynamic port.
Upvotes: 2