I am using InetAddress to determine if my server is online.
If the server is offline it will restart the server.
This process loops every 5 minutes to check once again if the server is online.
It works fine but now I need to figure out how to specify that I want to use port 43594 when checking the server status instead of the default port 80.
Thanks! Here's my code:
import java.net.InetAddress;
public class Test extends Thread {
public static void main(String args[]) {
try {
while (true) {
try
{
InetAddress address = InetAddress.getByName("cloudnine1999.no-ip.org");
boolean reachable = address.isReachable(10000);
if(reachable){
System.out.println("Online");
}
else{
System.out.println("Offline: Restarting Server...");
Runtime.getRuntime().exec("cmd /c start start.bat");
}
}
catch (Exception e)
{
e.printStackTrace();
}
Thread.sleep(5 * 60 * 1000);
}
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
EDIT:
Okay so I took someones advice and I made it into this. But now when I uncomment this line..
Runtime.getRuntime().exec("cmd /c start start.bat");
I get this error..
error: unreported exception IOException; must be caught or declared to be thrown
This is my current code:
import java.net.*;
import java.io.*;
public class Test extends Thread {
public static void main(String args[]) {
try {
while (true) {
SocketAddress sockaddr = new InetSocketAddress("cloudnine1999.no-ip.org", 43594);
Socket socket = new Socket();
boolean online = true;
try {
socket.connect(sockaddr, 10000);
}
catch (IOException IOException) {
online = false;
}
if(!online){
System.out.println("OFFLINE: Restarting Server..");
//Runtime.getRuntime().exec("cmd /c start start.bat");
}
if(online){
System.out.println("ONLINE");
}
Thread.sleep(1 * 10000);
}
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
As I already mentioned in the comments, according to the Javadoc isReachable isn't implemented in a way that would allow you to control the selected port. Actually, if it is allowed to do so by system privileges it will just ping the machine (ICMP request).
Doing it manually (ie, using a socket) will certainly work and isn't really more complicated and/or longer:
SocketAddress sockaddr = new InetSocketAddress("cloudnine1999.no-ip.org", 43594);
// Create your socket
Socket socket = new Socket();
boolean online = true;
// Connect with 10 s timeout
try {
socket.connect(sockaddr, 10000);
} catch (SocketTimeoutException stex) {
// treating timeout errors separately from other io exceptions
// may make sense
online=false;
} catch (IOException iOException) {
online = false;
} finally {
// As the close() operation can also throw an IOException
// it must caught here
try {
socket.close();
} catch (IOException ex) {
// feel free to do something moderately useful here, eg log the event
}
}
// Now, in your initial version all kinds of exceptions were swallowed by
// that "catch (Exception e)". You also need to handle the IOException
// exec() could throw:
if(!online){
System.out.println("OFFLINE: Restarting Server..");
try {
Runtime.getRuntime().exec("cmd /c start start.bat");
} catch (IOException ex) {
System.out.println("Restarting Server FAILED due to an exception " + ex.getMessage());
}
}
EDIT: forgot to handle IOException which also means the server isn't functioning, added
EDIT2: added the handling of the IOException that close() can throw
EDIT3: and exception handling for exec()
Related
an app in PC using JAVA io.socket which will sends json to a server device ESP8266on TCP on LAN network
when you are connected and when disconnect sequence is executed from java it self everything is ok .
java is client and device is server , when device cuts the connection (here lets use Hercules on localhost) the java program will not being noticed and when i try to write with outputstreamwriter it dose not trig an exception , exception will be executed after at least two writes to socket after the server is being disconnected and the last two writes which was not being received by server will return success! in java. i have read other programmers use a byte send to see if connection is still alive . the same problem is there too . if i send two write each 20 seconds time in between its going to be 60 seconds before java realize server is disconnected and if i send every 1 second is going to be a lot of ATcommand interrupts for nothing .
here is my code:
public boolean Write(String data){
System.out.println("StartSending");
if(TESocket.Connected)
{
Thread write = new Thread(new Runnable() {
#Override
public void run() {
try
{
outputStreamWriter.write(data);
outputStreamWriter.flush();
}
catch (IOException e)
{
TESocket.Connected=false;
System.out.println("Faild");
System.out.println(e.getCause());
}
}
});
write.start();
return true;
}
else
{
System.out.println("Not Connected");
return false;
}
}
The TESocket is class which handles Socket using Runnable and Connected is a static boolean since there is just one socket at a time here is the connect method
public boolean Connect(){
Thread connect = new Thread(new Runnable() {
#Override
public void run() {
try {
socket= new Socket("127.0.0.1",Integer.parseInt(port));
if(socket.isConnected())
{
inputStreamReader = new InputStreamReader(socket.getInputStream());
outputStreamWriter = new OutputStreamWriter(socket.getOutputStream());
TESocket.Connected=true;
System.out.println("Connected");
}
} catch (IOException e) {
System.out.println("Faild to Connect");
e.printStackTrace();
}
}
});
connect.start();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
if(TESocket.Connected)
return true;
else
return false;
}
how can i be noticed if server is out of reach with immediately after sending the write? or is there eny event for noticing that ? maybe some king of asynchronous socket? like it was in QT (Signal Slot for Disconnect)
well By reading method and setting a timeout solved this problem , thanks to reading some post
in read if i am still connected and not receiving any data time out will be thrown which bring me back to the first lie of the while loop
if i receive data i will be bigger than zero which reader will read data and flag the rec=true so the disconnect sequence dose not take in place
if i don't receive any data and timeout dose not occurs the rec=false and exception will not be thrown so the program will o to disconnect routine
setting the timeout to 1 millisecond makes it real-time (proportional to my work) in deadline detection
public boolean Read()
{
if (TESocket.Connected)
{
try {
socket.setSoTimeout(1000);
} catch (SocketException e) {
System.out.println("Problem Timeout");
e.printStackTrace();
}
Thread read = new Thread(new Runnable() {
#Override
public void run() {
int i;
boolean rec=false;
while (true)
{
char[] reader = new char[250];
try {
//while(!inputStreamReader.ready());
i=inputStreamReader.read(reader);
if(i>0) {
System.out.println(reader);
rec=true;
}
// Thread.sleep(2500);
if(!rec)
{
System.out.println("Disconnected");
TESocket.Connected=false;
inputStreamReader.close();
outputStreamWriter.close();
socket.close();
break;
}
rec=false;
}
catch (IOException e)
{
System.out.println("Connected");
}
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
read.start();
}
return true;
}
I'm currently writing a client-server application where data should be transferred to the server to process the data. For building the connection I use ServerSocket and Socket and for sending the data I use OutputStream + ObjectOutputStream on the client-side and InputStream + ObjectInputStream on the server-side. The connection is currently running on localhost.
The object I try to transfer is a serializable class that only contains String parameters.
The problem I'm facing now is that readObject() immediately throws an EOFException as soon as the OutputStreams of the client are initialized (which leads to an initialization of the InputStreams of the server at the same time) instead of waiting for input from the client.
I send the data from the client using this code:
public void send(DataSet dataSet) {
if (!clientStreamsEstablished) {
initiateClientStreams();
}
try {
out.writeObject(dataSet);
} catch (IOException e) {
e.printStackTrace();
}
}
This method is only called when I hit the "submit"-button in the UI so it will not be executed on start of the application.
The data is currently (already tried a ton of other approaches with and without while() loop etc., etc.) read on the server using this method:
private void waitForInput(ObjectInputStream in, InputStream listeningPort) {
boolean dataReceived = false;
DataSet dataSet = null;
System.out.println("waiting ...");
while (!dataReceived) {
try {
Object temp = in.readObject(); // <-- EOFException is thrown here
boolean test = false;
if (temp instanceof DataSet) {
dataSet = (DataSet) temp;
}
} catch (ClassNotFoundException | IOException e) {
e.printStackTrace();
break;
}
}
System.out.println("Test 2: " + dataSet.toString());
if (dataReceived) {
waitForInput(in, listeningPort);
}
}
As soon as the client thread on the server reaches this line (see code-comment above) I get this stacktrace:
java.io.EOFException
at java.io.ObjectInputStream$BlockDataInputStream.peekByte(ObjectInputStream.java:2626)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1321)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:373)
at com.labdashboardserver.ClientThread.waitForInput(ClientThread.java:53)
at com.labdashboardserver.ClientThread.run(ClientThread.java:43)
Exception in thread "Thread-2" java.lang.NullPointerException
at com.labdashboardserver.ClientThread.waitForInput(ClientThread.java:65)
at com.labdashboardserver.ClientThread.run(ClientThread.java:43)
The reason for the second part of the stacktrace containing the NullPointerException is apparent as due to the EOFExcpetion the dataSet never is initialized.
However from my point of view readObject() should block and wait for the client to send ANY data before starting to read it and throw an EOF. I feel like I read through half of Stack Overflow and other forums searching for an answer but the articles I found only discuss reading files or only immediate temporary streams which are closed afterwards.
Edit
I initialize the connection before calling the UI in my main method:
public static void main(String[] args) {
connector = new LabConnector();
connector.run();
if (connector.getConnectionEstablished()) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
frame = new LabUI();
frame.setVisible(true);
} catch (Exception e) {
JOptionPane.showMessageDialog(null,
"Error Message:\n" + e.getMessage() + "\nProgram shutting down!", "Critical Error", 0);
}
}
});
}
While in the LabConnector class I initialize the streams and connection like this:
public void run() {
try {
establishConnection();
} catch (UnknownHostException e) {
retryConnection(e);
} catch (IOException e) {
retryConnection(e);
}
if (connectionEstablished) {
initiateClientStreams();
}
}
private void establishConnection() throws UnknownHostException, IOException {
client = new Socket(HOST_IP_ADRESS, HOST_PORT);
JOptionPane.showMessageDialog(null, "Connected to Server!");
connectionEstablished = true;
}
private void initiateClientStreams() {
try {
sendingPort = client.getOutputStream();
out = new ObjectOutputStream(sendingPort);
clientStreamsEstablished = true;
} catch (IOException e) {
e.printStackTrace();
}
}
I have two classes - Provider and Requester:
Provider
import java.io.*;
import java.net.*;
public class Provider {
ServerSocket providerSocket;
Socket connection = null;
ObjectOutputStream out;
ObjectInputStream in;
String message;
Provider() {
}
void run() {
try {
// 1. creating a server socket
providerSocket = new ServerSocket(2004, 10);
// 2. Wait for connection
System.out.println("Waiting for connection");
connection = providerSocket.accept();
System.out.println(
"Connection received from " + connection.getInetAddress().getHostName());
// 3. get Input and Output streams
out = new ObjectOutputStream(connection.getOutputStream());
out.flush();
in = new ObjectInputStream(connection.getInputStream());
sendMessage("Connection successful");
// 4. The two parts communicate via the input and output streams
do {
try {
sendMessage(
"Please enter the phrase you wish to echo or the word FINISHED to exit");
message = (String) in.readObject();
sendMessage(message);
} catch (ClassNotFoundException classnot) {
System.err.println("Data received in unknown format");
}
} while (!message.equals("FINISHED"));
} catch (IOException ioException) {
ioException.printStackTrace();
} finally {
// 4: Closing connection
try {
in.close();
out.close();
providerSocket.close();
} catch (IOException ioException) {
ioException.printStackTrace();
}
}
}
void sendMessage(String msg) {
try {
out.writeObject(msg);
out.flush();
System.out.println("server>" + msg);
} catch (IOException ioException) {
ioException.printStackTrace();
}
}
public static void main(String args[]) {
Provider server = new Provider();
while (true) {
server.run();
}
}
}
Requester
import java.io.*;
import java.net.*;
import java.util.Scanner;
public class Requester {
Socket requestSocket;
ObjectOutputStream out;
ObjectInputStream in;
String message;
Scanner input;
Requester() {
input = new Scanner(System.in);
}
void run() {
try {
// 1. creating a socket to connect to the server
requestSocket = new Socket("127.0.0.1", 2004);
System.out.println("Connected to localhost in port 2004");
// 2. get Input and Output streams
out = new ObjectOutputStream(requestSocket.getOutputStream());
out.flush();
in = new ObjectInputStream(requestSocket.getInputStream());
// 3: Communicating with the server
try {
message = (String) in.readObject();
System.out.println("server>" + message);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
do {
try {
message = (String) in.readObject();
System.out.println(message);
message = input.nextLine();
sendMessage(message);
message = (String) in.readObject();
} catch (ClassNotFoundException classNot) {
System.err.println("data received in unknown format");
}
} while (!message.equals("FINISHED"));
} catch (UnknownHostException unknownHost) {
System.err.println("You are trying to connect to an unknown host!");
} catch (IOException ioException) {
ioException.printStackTrace();
} finally {
// 4: Closing connection
try {
in.close();
out.close();
requestSocket.close();
} catch (IOException ioException) {
ioException.printStackTrace();
}
}
}
void sendMessage(String msg) {
try {
out.writeObject(msg);
out.flush();
System.out.println("client>" + msg);
} catch (IOException ioException) {
ioException.printStackTrace();
}
}
public static void main(String args[]) {
Requester client = new Requester();
client.run();
}
}
The programs are basically meant to communicate with each other. The idea is that they each 'connect' with each other via sockets and the user should be able to enter something in the console window of Provider and have it echoed back onto the console of Requester. However, I am getting the following errors:
Provider
java.net.SocketException: Permission denied: listen failed
Requester
java.net.ConnectException: Connection refused: connect
(I can provide the rest of the errors if it would help in fixing the issue).
I have tried having the classes in the same project folder, in separate folders, and in different workspaces. I have also tried using Eclipse EE (Neon) and the SE (Oxygen). Recently, I have been having problems with ports and sockets (most notably with Tomcat and encountering the 'Cannot find free socket for debugger' in Eclipse). Would that have something to do with me being unable to run these programs?
Check your firewall settings. I was having similar problems when trying to use sockets. Make sure any relevant resources aren't blocked.
You might also want to run the command:
netstat -ano | findstr :2004
to check if that port is mistakenly in use already.
I am working on a Java client/server application that involves P2P communication over TCP. I'm trying to implement TCP Hole Punching as described here: http://www.brynosaurus.com/pub/net/p2pnat/#sec-tcp. This requires simultaneously listening on and attempting to establish an outgoing connection using the same local TCP port. Apparently, this should work if the SO_REUSEADDR socket option is used, which I am setting via the setReuseAddress() method in Java. However, this is not working as I expected. Here is some test code:
import java.io.IOException;
import java.net.*;
public class Test {
public static void main(String args[]) {
new Thread() {
public void run() {
try {
ServerSocket ss = new ServerSocket();
ss.setReuseAddress(true);
ss.bind(new InetSocketAddress(7077));
ss.accept();
} catch (Exception e) {
System.out.println("ServerSocket exception: " + e.getMessage());
}
}
}.start();
Socket s;
while (true) {
s = new Socket();
try {
s.setReuseAddress(true);
s.bind(new InetSocketAddress(7077));
s.connect(new InetSocketAddress("192.168.0.103", 7077));
break;
} catch (Exception e) {
System.out.println("Socket exception: " + e.getMessage());
try { s.close(); } catch (IOException e1) { }
try { Thread.sleep(1000); } catch (InterruptedException e1) { }
}
}
}
}
This works as expected in Windows 7: the ServerSocket listens on port 7077 in its own thread and the Socket repeatedly attempts to connect to 192.168.0.103:7077. However, under Linux (Ubuntu) only the first Socket connection attempt works, and subsequent attempts get the "Address already in use" BindException. Shouldn't I be able to establish an outgoing connection from a TCP source port that I'm also listening on simultaneously, and to reuse the local port number immediately after closing the socket, since I have the SO_REUSEADDR option enabled?
In Linux, both sockets need to set SO_REUSEADDR socket option. Thus, if we want two sockets, sock1 and sock2 to be bound ot the same port, then s2 would be able to reuse the port/address only if both sock1 and sock2 set SO_REUSEADDR.
You are never closing your client socket, unless there is an exception, making the point of SO_REUSEADDR a no-op.
....
s = new Socket();
try {
// ...
} catch (Exception e) {
System.out.println("Socket exception: " + e.getMessage());
// remove try block from here
try { Thread.sleep(1000); } catch (InterruptedException e1) { }
} finally {
try { s.close(); } catch (IOException e1) { }
}
....
In the above, I moved the closing of the socket to a newly created finally block so it is always executed, even if you break out the global while loop.
Since the socket is now closed under all conditions, the SO_REUSEADDR will use correctly now.
I'm working on an Android application that uses sockets. I have a function called initializeStreams() which opens the socket and attempts a connection. This function throws a ConnectException if the connection could not be established. But for some reason, in the code that calls initializeStreams(), which has a catch block for ConnectException, the log prints out its own stack trace for the exception instead of going to the catch block. The catch block is never reached at all, even though the exact exception is being thrown. Here's the code:
The try block:
try {
initializeStreams();
/* other code */
} catch (ConnectException e) {
Log.i(TAG, "caught connect exception");
}
initializeStreams():
public void initializeStreams() throws ConnectException {
try {
Log.i(TAG, "Attempting to connect");
requestSocket = new Socket(SERVER_ADDR, PORT);
/* other code */
} catch (IOException e) {
e.printStackTrace();
}
I can't figure this out, so any help would be much appreciated.
You need to chain your Exception throwing it in the catch block. Try the following:
public void initializeStreams() throws ConnectException {
try {
Log.i(TAG, "Attempting to connect");
requestSocket = new Socket(SERVER_ADDR, PORT);
/* other code */
} catch(ConnectException e){
throw e;
}
catch (IOException e) {
e.printStackTrace();
}
ConnectException extends SocketException which in turn extends IOException, so the catch for IOException in initializeStreams() catches the ConnectException. I would just remove that try/catch block altogether: there's not much point in returning cleanly from this method without a connection.