📄 mcgroupimpl.java
字号:
/*
* Created on 14-Jun-2004
* Created by Paul Gardner
* Copyright (C) 2004, 2005, 2006 Aelitis, All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* AELITIS, SAS au capital de 46,603.30 euros
* 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France.
*
*/
package com.aelitis.net.udp.mc.impl;
import java.net.*;
import java.util.*;
import org.gudy.azureus2.core3.util.AEMonitor;
import org.gudy.azureus2.core3.util.AEThread;
import org.gudy.azureus2.plugins.utils.UTTimer;
import org.gudy.azureus2.plugins.utils.UTTimerEvent;
import org.gudy.azureus2.plugins.utils.UTTimerEventPerformer;
import org.gudy.azureus2.pluginsimpl.local.utils.UTTimerImpl;
import com.aelitis.net.udp.mc.MCGroup;
import com.aelitis.net.udp.mc.MCGroupAdapter;
import com.aelitis.net.udp.mc.MCGroupException;
/**
* @author parg
*
*/
public class
MCGroupImpl
implements MCGroup
{
private final static int TTL = 4;
private final static int PACKET_SIZE = 8192;
private static Map singletons = new HashMap();
private static AEMonitor class_mon = new AEMonitor( "MCGroup:class" );
public static MCGroupImpl
getSingleton(
MCGroupAdapter adapter,
String group_address,
int group_port,
int control_port,
String[] interfaces )
throws MCGroupException
{
try{
class_mon.enter();
String key = group_address + ":" + group_port + ":" + control_port;
MCGroupImpl singleton = (MCGroupImpl)singletons.get( key );
if ( singleton == null ){
singleton = new MCGroupImpl( adapter, group_address, group_port, control_port, interfaces );
singletons.put( key, singleton );
}
return( singleton );
}finally{
class_mon.exit();
}
}
private MCGroupAdapter adapter;
private String group_address_str;
private int group_port;
private int control_port;
protected InetSocketAddress group_address;
private String[] selected_interfaces;
private boolean ttl_problem_reported = true; // remove these diagnostic reports on win98
private boolean sso_problem_reported = true; // remove these diagnostic reports on win98
protected AEMonitor this_mon = new AEMonitor( "MCGroup" );
private Map current_registrations = new HashMap();
public
MCGroupImpl(
MCGroupAdapter _adapter,
String _group_address,
int _group_port,
int _control_port,
String[] _interfaces )
throws MCGroupException
{
adapter = _adapter;
group_address_str = _group_address;
group_port = _group_port;
control_port = _control_port;
selected_interfaces = _interfaces;
try{
group_address = new InetSocketAddress(InetAddress.getByName(group_address_str), 0 );
processNetworkInterfaces( true );
UTTimer timer = new UTTimerImpl( "MCGroup:refresher", true );
timer.addPeriodicEvent(
60*1000,
new UTTimerEventPerformer()
{
public void
perform(
UTTimerEvent event )
{
try{
processNetworkInterfaces( false );
}catch( Throwable e ){
adapter.log(e);
}
}
});
}catch( Throwable e ){
throw( new MCGroupException( "Failed to initialise MCGroup", e ));
}
}
protected void
processNetworkInterfaces(
boolean start_of_day )
throws SocketException
{
Map new_registrations = new HashMap();
List changed_interfaces = new ArrayList();
try{
this_mon.enter();
Enumeration network_interfaces = NetworkInterface.getNetworkInterfaces();
while (network_interfaces.hasMoreElements()){
final NetworkInterface network_interface = (NetworkInterface)network_interfaces.nextElement();
if ( !interfaceSelected( network_interface )){
if ( start_of_day ){
adapter.trace( "ignoring interface " + network_interface.getName() + ":" + network_interface.getDisplayName() + ", not selected" );
}
continue;
}
Set old_address_set = (Set)current_registrations.get( network_interface );
if ( old_address_set == null ){
old_address_set = new HashSet();
}
Set new_address_set = new HashSet();
new_registrations.put( network_interface, new_address_set );
Enumeration ni_addresses = network_interface.getInetAddresses();
while (ni_addresses.hasMoreElements()){
final InetAddress ni_address = (InetAddress)ni_addresses.nextElement();
new_address_set.add( ni_address );
if ( old_address_set.contains( ni_address )){
// already established
continue;
}
// turn on loopback to see if it helps for local host UPnP devices
// nah, turn it off again, it didn;t
if ( ni_address.isLoopbackAddress()){
if ( start_of_day ){
adapter.trace( "ignoring loopback address " + ni_address + ", interface " + network_interface.getName());
}
continue;
}
if ( ni_address instanceof Inet6Address ){
if ( start_of_day ){
adapter.trace( "ignoring IPv6 address " + ni_address + ", interface " + network_interface.getName());
}
continue;
}
if ( !start_of_day ){
if ( !changed_interfaces.contains( network_interface )){
changed_interfaces.add( network_interface );
}
}
try{
// set up group
final MulticastSocket mc_sock = new MulticastSocket( group_port );
mc_sock.setReuseAddress(true);
// windows 98 doesn't support setTimeToLive
try{
mc_sock.setTimeToLive(TTL);
}catch( Throwable e ){
if ( !ttl_problem_reported ){
ttl_problem_reported = true;
adapter.log( e );
}
}
String addresses_string = "";
Enumeration it = network_interface.getInetAddresses();
while (it.hasMoreElements()){
InetAddress addr = (InetAddress)it.nextElement();
addresses_string += (addresses_string.length()==0?"":",") + addr;
}
adapter.trace( "group = " + group_address +"/" +
network_interface.getName()+":"+
network_interface.getDisplayName() + "-" + addresses_string +": started" );
mc_sock.joinGroup( group_address, network_interface );
mc_sock.setNetworkInterface( network_interface );
// note that false ENABLES loopback mode which is what we want
mc_sock.setLoopbackMode(false);
Runtime.getRuntime().addShutdownHook(
new AEThread("MCGroup:VMShutdown")
{
public void
runSupport()
{
try{
mc_sock.leaveGroup( group_address, network_interface );
}catch( Throwable e ){
adapter.log( e );
}
}
});
new AEThread("MCGroup:MCListener", true )
{
public void
runSupport()
{
handleSocket( network_interface, ni_address, mc_sock, true );
}
}.start();
}catch( Throwable e ){
adapter.log( e );
}
// now do the incoming control listener
try{
final DatagramSocket control_socket = new DatagramSocket( null );
control_socket.setReuseAddress( true );
control_socket.bind( new InetSocketAddress(ni_address, control_port ));
if ( control_port == 0 ){
control_port = control_socket.getLocalPort();
// System.out.println( "local port = " + control_port );
}
new AEThread( "MCGroup:CtrlListener", true )
{
public void
runSupport()
{
handleSocket( network_interface, ni_address, control_socket, false );
}
}.start();
}catch( Throwable e ){
adapter.log( e );
}
}
}
}finally{
current_registrations = new_registrations;
this_mon.exit();
}
for (int i=0;i<changed_interfaces.size();i++){
adapter.interfaceChanged((NetworkInterface)changed_interfaces.get(i));
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -