void setBufferSizes() { if (sock != null) { try { sock.setSendBufferSize(ucast_send_buf_size); } catch (Throwable ex) { Trace.warn("UDP.setBufferSizes()", "failed setting ucast_send_buf_size in sock: " + ex); } try { sock.setReceiveBufferSize(ucast_recv_buf_size); } catch (Throwable ex) { Trace.warn("UDP.setBufferSizes()", "failed setting ucast_recv_buf_size in sock: " + ex); } } if (mcast_sock != null) { try { mcast_sock.setSendBufferSize(mcast_send_buf_size); } catch (Throwable ex) { Trace.warn( "UDP.setBufferSizes()", "failed setting mcast_send_buf_size in mcast_sock: " + ex); } try { mcast_sock.setReceiveBufferSize(mcast_recv_buf_size); } catch (Throwable ex) { Trace.warn( "UDP.setBufferSizes()", "failed setting mcast_recv_buf_size in mcast_sock: " + ex); } } }
void closeMulticastSocket() { if (mcast_sock != null) { try { if (mcast_addr != null) { // by sending a dummy packet the thread will be awakened sendDummyPacket(mcast_addr.getIpAddress(), mcast_addr.getPort()); Util.sleep(300); mcast_sock.leaveGroup(mcast_addr.getIpAddress()); } mcast_sock.close(); // this will cause the mcast receiver thread to break out of its loop mcast_sock = null; if (Trace.trace) { Trace.info("UDP.closeMulticastSocket()", "multicast socket closed"); } } catch (IOException ex) { } mcast_addr = null; } }
String dumpSocketInfo() throws Exception { StringBuffer sb = new StringBuffer(); sb.append("local_addr=").append(local_addr); sb.append(", mcast_addr=").append(mcast_addr); sb.append(", bind_addr=").append(bind_addr); sb.append(", ttl=").append(ip_ttl); if (sock != null) { sb.append("\nsocket: bound to "); sb.append(sock.getLocalAddress().getHostAddress()).append(":").append(sock.getLocalPort()); sb.append(", receive buffer size=").append(sock.getReceiveBufferSize()); sb.append(", send buffer size=").append(sock.getSendBufferSize()); } if (mcast_sock != null) { sb.append("\nmulticast socket: bound to "); sb.append(mcast_sock.getInterface().getHostAddress()) .append(":") .append(mcast_sock.getLocalPort()); sb.append(", send buffer size=").append(mcast_sock.getSendBufferSize()); sb.append(", receive buffer size=").append(mcast_sock.getReceiveBufferSize()); } return sb.toString(); }
/** * Create UDP sender and receiver sockets. Currently there are 2 sockets (sending and receiving). * This is due to Linux's non-BSD compatibility in the JDK port (see DESIGN). */ void createSockets() throws Exception { InetAddress tmp_addr = null; // bind_addr not set, try to assign one by default. This is needed on Windows // changed by bela Feb 12 2003: by default multicast sockets will be bound to all network // interfaces // CHANGED *BACK* by bela March 13 2003: binding to all interfaces did not result in a correct // local_addr. As a matter of fact, comparison between e.g. 0.0.0.0:1234 (on hostA) and // 0.0.0.0:1.2.3.4 (on hostB) would fail ! if (bind_addr == null) { InetAddress[] interfaces = InetAddress.getAllByName(InetAddress.getLocalHost().getHostAddress()); if (interfaces != null && interfaces.length > 0) bind_addr = interfaces[0]; } if (bind_addr == null) bind_addr = InetAddress.getLocalHost(); if (bind_addr != null && Trace.trace) { Trace.info( "UDP.createSockets()", "unicast sockets will use interface " + bind_addr.getHostAddress()); // 2. Create socket for receiving unicast UDP packets. The address and port // of this socket will be our local address (local_addr) // 27-6-2003 bgooren, find available port in range (start_port, start_port+port_range) } int rcv_port = bind_port, max_port = bind_port + port_range; while (rcv_port <= max_port) { try { sock = new DatagramSocket(rcv_port, bind_addr); break; } catch (SocketException bind_ex) { // Cannot listen on this port rcv_port++; } catch (SecurityException sec_ex) { // Not allowed to list on this port rcv_port++; } // Cannot listen at all, throw an Exception if (rcv_port == max_port + 1) { // +1 due to the increment above throw new Exception( "UDP.createSockets(): cannot list on any port in range " + bind_port + "-" + (bind_port + port_range)); } } // ucast_recv_sock=new DatagramSocket(bind_port, bind_addr); if (sock == null) { throw new Exception("UDP.createSocket(): sock is null"); } local_addr = new IpAddress(sock.getLocalAddress(), sock.getLocalPort()); if (additional_data != null) { local_addr.setAdditionalData(additional_data); // 3. Create socket for receiving IP multicast packets } if (ip_mcast) { mcast_sock = new MulticastSocket(mcast_port); mcast_sock.setTimeToLive(ip_ttl); if (bind_addr != null) { mcast_sock.setInterface(bind_addr); } tmp_addr = InetAddress.getByName(mcast_addr_name); mcast_addr = new IpAddress(tmp_addr, mcast_port); mcast_sock.joinGroup(tmp_addr); } setBufferSizes(); if (Trace.trace) { Trace.info("UDP.createSockets()", "socket information:\n" + dumpSocketInfo()); } }
public void run() { DatagramPacket packet; byte receive_buf[] = new byte[65535]; int len; byte[] tmp, data; // moved out of loop to avoid excessive object creations (bela March 8 2001) packet = new DatagramPacket(receive_buf, receive_buf.length); while (mcast_receiver != null && mcast_sock != null) { try { packet.setData(receive_buf, 0, receive_buf.length); mcast_sock.receive(packet); len = packet.getLength(); data = packet.getData(); if (len == 1 && data[0] == 0) { if (Trace.debug) { Trace.info("UDP.run()", "received dummy packet"); } continue; } if (len == 4) { // received a diagnostics probe if (data[0] == 'd' && data[1] == 'i' && data[2] == 'a' && data[3] == 'g') { handleDiagnosticProbe(packet.getAddress(), packet.getPort()); continue; } } if (Trace.debug) { Trace.info( "UDP.receive()", "received (mcast) " + packet.getLength() + " bytes from " + packet.getAddress() + ":" + packet.getPort() + " (size=" + len + " bytes)"); } if (len > receive_buf.length) { Trace.error( "UDP.run()", "size of the received packet (" + len + ") is bigger than " + "allocated buffer (" + receive_buf.length + "): will not be able to handle packet. " + "Use the FRAG protocol and make its frag_size lower than " + receive_buf.length); } if (Version.compareTo(data) == false) { Trace.warn( "UDP.run()", "packet from " + packet.getAddress() + ":" + packet.getPort() + " has different version (" + Version.printVersionId(data, Version.version_id.length) + ") from ours (" + Version.printVersionId(Version.version_id) + "). This may cause problems"); } if (use_incoming_packet_handler) { tmp = new byte[len]; System.arraycopy(data, 0, tmp, 0, len); incoming_queue.add(tmp); } else { handleIncomingUdpPacket(data); } } catch (SocketException sock_ex) { if (Trace.trace) { Trace.info("UDP.run()", "multicast socket is closed, exception=" + sock_ex); } break; } catch (InterruptedIOException io_ex) { // thread was interrupted ; // go back to top of loop, where we will terminate loop } catch (Throwable ex) { Trace.error("UDP.run()", "exception=" + ex + ", stack trace=" + Util.printStackTrace(ex)); Util.sleep(300); // so we don't get into 100% cpu spinning (should NEVER happen !) } } if (Trace.trace) { Trace.info("UDP.run()", "multicast thread terminated"); } }