Interrupt pool Thread
MarkusRost opened this issue · comments
Hello,
I use the SendArpRequest example to read the MAC adress of an other IP. When the IP is not reachable, a thread named "pool-15-thread-1" is not stop and still alive.
How can I stop these Thread?
Here my code:
`import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.pcap4j.core.BpfProgram.BpfCompileMode;
import org.pcap4j.core.NotOpenException;
import org.pcap4j.core.PacketListener;
import org.pcap4j.core.PcapHandle;
import org.pcap4j.core.PcapNativeException;
import org.pcap4j.core.PcapNetworkInterface;
import org.pcap4j.core.PcapNetworkInterface.PromiscuousMode;
import org.pcap4j.core.Pcaps;
import org.pcap4j.packet.ArpPacket;
import org.pcap4j.packet.EthernetPacket;
import org.pcap4j.packet.Packet;
import org.pcap4j.packet.namednumber.ArpHardwareType;
import org.pcap4j.packet.namednumber.ArpOperation;
import org.pcap4j.packet.namednumber.EtherType;
import org.pcap4j.util.ByteArrays;
import org.pcap4j.util.MacAddress;
public class SendArpRequest
{
private static final String COUNT_KEY = SendArpRequest.class.getName() + ".count";
private static int COUNT;
private static final String READ_TIMEOUT_KEY = SendArpRequest.class.getName() + ".readTimeout";
private static int READ_TIMEOUT; // [ms]
private static final String SNAPLEN_KEY = SendArpRequest.class.getName() + ".snaplen";
private static int SNAPLEN; // [bytes]
private String sourceIP = "";
private MacAddress sourceMac = MacAddress.getByName( "fe:00:01:02:03:04" );
private static MacAddress resolvedAddr = null;
private String destinationIP = "";
private Debug debug;
private ConfigRead config;
public SendArpRequest( Debug d, ConfigRead c, String sourceIP, String sourceMac )
{
this.debug = d;
this.config = c;
this.sourceIP = sourceIP;
this.sourceMac = MacAddress.getByName( sourceMac );
COUNT = Integer.getInteger( COUNT_KEY, config.getArpCount() );
READ_TIMEOUT = Integer.getInteger( READ_TIMEOUT_KEY, config.getArpTimeout() ); // [ms]
SNAPLEN = Integer.getInteger( SNAPLEN_KEY, config.getArpPacketSize() ); // [bytes]
debug.print( 2, "ARP Objekt initialisiert mit SourceIP: " + sourceIP + " und Source Mac: " + sourceMac );
}
public String searchMacAddress( String destinationIP ) throws RuntimeException
{
debug.print( 2, "Suche nach Macadresse für: " + destinationIP );
String erg = "";
Boolean state = true;
this.destinationIP = destinationIP;
resolvedAddr = null;
/*
System.out.println(COUNT_KEY + ": " + COUNT);
System.out.println(READ_TIMEOUT_KEY + ": " + READ_TIMEOUT);
System.out.println(SNAPLEN_KEY + ": " + SNAPLEN);
System.out.println("\n");
*/
PcapNetworkInterface nif;
try
{
nif = Pcaps.getDevByAddress( InetAddress.getByName( this.sourceIP ) );
}
catch( Exception e )
{
debug.print( 1, "Source Netzwerk Interface nicht gefunden: " + e.getMessage() );
return erg;
}
if( nif == null )
{
debug.print( 1, "Source Netzwerk Interface nicht gefunden!" );
return erg;
}
debug.print( 2, "Suche über folgendes Inerface: " + nif.getName() + " (" + nif.getDescription() + ")" );
PcapHandle handle = null;
PcapHandle sendHandle = null;
ExecutorService pool = null;
try
{
handle = nif.openLive( SNAPLEN, PromiscuousMode.PROMISCUOUS, READ_TIMEOUT );
sendHandle = nif.openLive( SNAPLEN, PromiscuousMode.PROMISCUOUS, READ_TIMEOUT );
pool = Executors.newSingleThreadExecutor();
handle.setFilter( "arp and src host " + destinationIP + " and dst host " + this.sourceIP + " and ether dst " + Pcaps.toBpfString( this.sourceMac ), BpfCompileMode.OPTIMIZE );
PacketListener listener = new PacketListener()
{
public void gotPacket( Packet packet )
{
if( packet.contains( ArpPacket.class ))
{
ArpPacket arp = packet.get( ArpPacket.class );
if( arp.getHeader().getOperation().equals( ArpOperation.REPLY ))
{
SendArpRequest.resolvedAddr = arp.getHeader().getSrcHardwareAddr();
}
}
debug.print( 3, "Empfangenes Packet: " + packet );
}
};
Task t = new Task( handle, listener );
pool.execute( t );
ArpPacket.Builder arpBuilder = new ArpPacket.Builder();
try
{
arpBuilder
.hardwareType( ArpHardwareType.ETHERNET )
.protocolType( EtherType.IPV4 )
.hardwareAddrLength( (byte)MacAddress.SIZE_IN_BYTES )
.protocolAddrLength( (byte)ByteArrays.INET4_ADDRESS_SIZE_IN_BYTES )
.operation( ArpOperation.REQUEST )
.srcHardwareAddr( this.sourceMac )
.srcProtocolAddr( InetAddress.getByName( this.sourceIP ))
.dstHardwareAddr( MacAddress.ETHER_BROADCAST_ADDRESS )
.dstProtocolAddr( InetAddress.getByName( destinationIP ));
}
catch( UnknownHostException e )
{
debug.print( 1, "Fehler beim Bau des ARP Pakets: " + e.getMessage() );
return erg;
}
EthernetPacket.Builder etherBuilder = new EthernetPacket.Builder();
etherBuilder.dstAddr( MacAddress.ETHER_BROADCAST_ADDRESS )
.srcAddr( this.sourceMac )
.type( EtherType.ARP )
.payloadBuilder( arpBuilder )
.paddingAtBuild( true );
for( int i = 0; i < COUNT; i++ )
{
Packet p = etherBuilder.build();
debug.print( 3, "Gesendetes Packet: " + p );
sendHandle.sendPacket(p);
try
{
Thread.sleep( 1000 );
}
catch( InterruptedException e )
{
break;
}
}
debug.print( 2, "Pakete gesendet" );
int i = 0;
while( true )
{
if( resolvedAddr != null )
{
break;
}
i = i + 1;
if( i >= 10 )
{
pool.shutdown();
pool.shutdownNow();
throwRuntimeException();
}
try
{
Thread.sleep( 100 );
}
catch( InterruptedException e )
{
break;
}
}
}
catch( RuntimeException re )
{
debug.print( 1, "Runtime Error bei ARP Abfrage: " + re.getMessage() );
state = false;
throw new RuntimeException( re );
}
catch( Exception e )
{
debug.print( 1, "Fehler bei ARP Abfrage: " + e.getMessage() );
return erg;
}
finally
{
if( state == true )
{
if (handle != null && handle.isOpen())
{
handle.close();
}
if (sendHandle != null && sendHandle.isOpen())
{
sendHandle.close();
}
if (pool != null && !pool.isShutdown())
{
pool.shutdown();
}
}
debug.print( 2, destinationIP + " was resolved to " + resolvedAddr );
}
return resolvedAddr.toString();
}
private void throwRuntimeException()
{
throw new RuntimeException( "RunTime Fehler bei " + destinationIP );
}
private static class Task implements Runnable
{
private PcapHandle handle;
private PacketListener listener;
public Task(PcapHandle handle, PacketListener listener)
{
this.handle = handle;
this.listener = listener;
}
@Override
public void run()
{
try
{
handle.loop(COUNT, listener);
}
catch (PcapNativeException e)
{
e.printStackTrace();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
catch (NotOpenException e)
{
e.printStackTrace();
}
}
}
}`
Thanks
Markus