/** * Gets a <tt>MultiplexedDatagramSocket</tt> which filters <tt>DatagramPacket</tt>s away from this * <tt>DatagramSocket</tt> using a specific <tt>DatagramPacketFilter</tt>. If such a * <tt>MultiplexedDatagramSocket</tt> does not exist in this instance, it is created. * * @param filter the <tt>DatagramPacketFilter</tt> to get a <tt>MultiplexedDatagramSocket</tt> for * @return a <tt>MultiplexedDatagramSocket</tt> which filters <tt>DatagramPacket</tt>s away from * this <tt>DatagramSocket</tt> using the specified <tt>filter</tt> * @throws SocketException if creating the <tt>MultiplexedDatagramSocket</tt> for the specified * <tt>filter</tt> fails */ public MultiplexedDatagramSocket getSocket(DatagramPacketFilter filter) throws SocketException { if (filter == null) throw new NullPointerException("filter"); synchronized (socketsSyncRoot) { /* * If a socket for the specified filter exists already, do not * create a new one and return the existing. */ for (MultiplexedDatagramSocket socket : sockets) if (filter.equals(socket.getFilter())) return socket; // Create a new socket for the specified filter. MultiplexedDatagramSocket socket = new MultiplexedDatagramSocket(this, filter); // Remember the new socket. int socketCount = sockets.length; if (socketCount == 0) sockets = new MultiplexedDatagramSocket[] {socket}; else { MultiplexedDatagramSocket[] newSockets = new MultiplexedDatagramSocket[socketCount + 1]; System.arraycopy(sockets, 0, newSockets, 0, socketCount); newSockets[socketCount] = socket; sockets = newSockets; } return socket; } }
/** * Receives a <tt>DatagramPacket</tt> from a specific list of <tt>DatagramPacket</tt>s if it is * not empty or from the network if the specified list is empty. When this method returns, the * <tt>DatagramPacket</tt>'s buffer is filled with the data received. The datagram packet also * contains the sender's IP address, and the port number on the sender's machine. * * @param received the list of previously received <tt>DatagramPacket</tt> from which the first is * to be removed and returned if available * @param p the <tt>DatagramPacket</tt> into which to place the incoming data * @throws IOException if an I/O error occurs */ private void receive(List<DatagramPacket> received, DatagramPacket p) throws IOException { DatagramPacket r = null; do { boolean doReceive; synchronized (receiveSyncRoot) { if (received.isEmpty()) { if (inReceive) { doReceive = false; try { receiveSyncRoot.wait(); } catch (InterruptedException iex) { continue; } } else { doReceive = true; inReceive = true; } } else { doReceive = false; r = received.remove(0); } } if (doReceive) { try { super.receive(p); synchronized (receiveSyncRoot) { synchronized (socketsSyncRoot) { boolean accepted = false; for (MultiplexedDatagramSocket socket : sockets) if (socket.getFilter().accept(p)) { socket.received.add(clone(p)); accepted = true; /* * Emil: Don't break because we want all * filtering sockets to get this. */ // break; } if (!accepted) this.received.add(clone(p)); } } } finally { synchronized (receiveSyncRoot) { inReceive = false; receiveSyncRoot.notify(); } } } } while (r == null); copy(r, p); }