001package arcommon.net;
002
003import java.io.IOException;
004import java.net.DatagramPacket;
005import java.net.InetAddress;
006import java.net.MulticastSocket;
007import java.net.SocketException;
008
009public class MulticastConnection {
010    private int port;
011    private MulticastSocket socket;
012    private InetAddress address;
013    private boolean closed;
014    private boolean networkAvailable;
015
016    @SuppressWarnings("deprecation")
017    public MulticastConnection(String host, int pport) {
018        try {
019            port = pport;
020            address = InetAddress.getByName(host);
021            socket = new MulticastSocket(port);
022        } catch (IOException e) {
023            throw new RuntimeException(e);
024        }
025        try {
026            socket.joinGroup(address);
027            networkAvailable = true;
028        } catch (SocketException e) {
029            if (e.getMessage().equals("No such device")) {
030                closed = true;
031                networkAvailable = false;
032            } else {
033                throw new RuntimeException(e);
034            }
035        } catch (IOException e) {
036            throw new RuntimeException(e);
037        }
038    }
039    
040    private void validateState() {
041        if (!networkAvailable) {
042            throw new RuntimeException("Network is not available");
043        }
044        if (closed) {
045            throw new RuntimeException("This connection is already closed");
046        }
047    }
048
049    public String receive() {
050        validateState();
051        
052        try {
053            byte[] buffer = new byte[256];
054            DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
055            socket.receive(packet);
056
057            String received = new String(packet.getData(), 0, packet.getLength());
058            return received;
059        } catch (SocketException e) {
060            if (e.getMessage().equals("Socket closed") || e.getMessage().equals("socket closed")) {
061                if (closed) {
062                    return null;
063                }
064            }
065            throw new RuntimeException(e);
066        } catch (IOException e) {
067            throw new RuntimeException(e);
068        }
069    }
070    
071    public void send(String message) {
072        validateState();
073
074        try {
075            byte[] bytes = message.getBytes();
076            DatagramPacket packet = new DatagramPacket(bytes, bytes.length, address, port);
077            socket.send(packet);
078        } catch (IOException e) {
079            throw new RuntimeException(e);
080        }
081    }
082    
083    @SuppressWarnings("deprecation")
084    public synchronized void close() {
085        if (closed) {
086            return ;
087        }
088        
089        try {
090            closed = true;
091            socket.leaveGroup(address);
092        } catch (SocketException e) {
093            if (e.getMessage().equals("No such device")) {
094                networkAvailable = false;
095            } else {
096                throw new RuntimeException(e);
097            }
098        } catch (IOException e) {
099            throw new RuntimeException(e);
100        }
101        socket.close();
102    }
103
104    public boolean isNetworkAvailable() {
105        return networkAvailable;
106    }
107    
108    public boolean getClosed() {
109        return closed;
110    }
111}