Tyrus: silent server start failure - java

We are currently trying to implement WebSocket server using Tyrus and everything went alright (server-client communication worked well) until we tried to test what happens if server initialization fails (e.g. bad port).
The underlying code throws SocketException (permission denied). The exception is written to stdout but the server proceeds and the program continues beyond start() method.
public void runServer() {
// bad port number
Server server = new Server("localhost", 10, "/websockets", null, EchoEndpoint.class);
try {
server.start();
// this line should not be printed
System.out.println("Server started");
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
System.out.print("Please press a key to stop the server.");
reader.readLine();
} catch (Exception e) {
System.out.println("Exception caught");
e.printStackTrace();
} finally {
server.stop();
}
}
Is there any way to detect whether the server started successfully?
EDIT: We know we cannot use port 10 (that is why we tried it). We just need to check whether the server is running (by somehow catching the exception). (And we do not want to test it by an attempt to send some dummy data with a client - that would not really fix the problem)

Your port number '10' is too low to be used by regular user. You must be privileged user or use a port number greater than 1024:
Server server = new Server("localhost", 1025, "/websockets", null, EchoEndpoint.class)

Related

Socket stream not able to flush

I am writing an app for android 4.2, currently debugged on a Samsung s2+.
The app establishes a connection to a server using a Socket, and the server is using a ServerSocket and the establish()-method to get its socket. So far so good. Since I have to make all the networking in android in a new thread, I created a new class extending Thread which communicates with an underlying Activity (for user input) using a BlockingQueue. The threads run method:
public void run() {
Socket s = null;
try {
s = new Socket(info.getIp(), 1337);
} catch (IOException e) {
e.printStackTrace();
}
String code = null;
try {
code = queue.take();
} catch (InterruptedException e1) {
e1.printStackTrace();
}
Log.e("DONE", code);
PrintWriter out = null;
try {
out = new PrintWriter(s.getOutputStream());
} catch (IOException e) {
e.printStackTrace();
}
out.write(code);
out.flush();
}
The connection is up and running, and the logged message "DONE"+code is logged. However, nothing is received on the server side until I force close the app. Is an android thread not able to flush data?
EDIT: If close the socket immediately after writing to it, the text arrives without having to force close the app. Why can't I read the text in the server if the socket is still alive?
try add a newline to the string you sent to server , something like :
out.write(code+"\n");
out.flush();
and as EJP said above put the out.write inside the try / catch
A socket connection only provides the ability to send and receive bytes. As soon as the client sends a byte, the server will receive it. Also, as soon as a client is disconnected, the server will know about it - this is about the extend of what you get from sockets.
The concept of a message does not exist at this level. A message is instead defined by whatever lies above the socket, so most protocols use one or more of three different ways to chunk streams of bytes into "messages"
a special byte or sequence of bytes indicates the end of the message (a new line for example, which seems to have been your case :)
each message starts with x bytes which provide the length of the message (so a simple "05aaaaa02bb" stream of bytes might mean that 2 messages were send - "aaaaa" and "bb"
the entire socket connection lasts for a single message (end of message comes when the connection is closed). This is how HTTP 1.0 works for example.

How to listen to incoming packets on a port?

I want to listen to incoming packets on port 19132 and print them out as they come, but so far my code doesn't exactly print anything at all. There is a server forwarding the packets through port 19132 to my computer, and the port is open and enabled, but still nothing is printed.
public static void listenToPort(){
try{
ServerSocket serverSocket = new ServerSocket(19132);
Socket socket = serverSocket.accept();
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
while(true){
try{
System.out.println(in.readLine());
}
catch(IOException e){
System.out.println("Connection to server lost!");
System.exit(1);
break;
}
}
}
catch(IOException e){
System.out.println(e.getMessage());
}
}
On the server side there is info being sent, but the client program (this script) doesn't receive anything, what's the problem?
You are reading lines, not 'packets'. If the data being sent to this port doesn't contain newlines, readLine() will block forever, or until the peer closes the connection.
On the other hand when it does read something, or EOS, your code will spin forever printing null, because you aren't checking for readLine() returning null, at which point you must close the socket and exit the loop.
Not to mention, it might be entirely possible that the System.exit doesn't give enough time for the console to flush it's output (i'm not 100% sure if System.exit will or won't cause a flush in System.out and System.err).
Why don't you attach a debugger to your server process and see if it's even getting past the in.readLine()? As one of the other posters mentioned, if you're not sending a newline character, in.readLine() would block until you do.
Secondly, you shouldn't really use System.exit. It's bad form in most cases and leads to people wondering why the hell an app would just randomly quit. If you want to exit an app, you should allow the code to return back to the main() method, and from there you can do a System.exit if necessary.

Android Sockets - Client side IOException

I'm trying to connect to a simple Java server on my computer (in the future a true server, but I'm just learning how to program with sockets first. When I try to connect, the application on the phone throws an IOException. However, on the emulator, it does NOT.
I do have:
< uses-permission android:name="android.permission.INTERNET"/>
included in the manifest. And here's the code block that's executed when I hit open:
try {
responseField.setText("Opening socket...");
Socket socket = new Socket(getIP(),Integer.parseInt(getPort()));
responseField.setText("Socket opened. Initializing out...");
out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
responseField.setText("Done. Initializing in...");
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
responseField.setText("Done.");
} catch (NumberFormatException e1) {
responseField.setText("NumberFormatException");
} catch (UnknownHostException e1) {
responseField.setText("UnknownHostException");
} catch (IOException e1) {
responseField.setText("IOException");
}
Are you making sure that the server end uses a ServerSocket and uses the ServerSocker.accept() method?
So it seems that a weak Wi-Fi signal is causing error. I tried to surf the web (Google, CNN, etc.) afterward, and I could not. So I will just have to test on the emulator for now, or in a stronger signal. Thanks
If you were able to connect to the web before (I am assuming) but not after, then its not a problem with the wifi strength. Also depending on place you are surfing, the wifi router may have been configured not to allow such connections. Try to ping your server IP using a different computer within the same network and see whether you can ping. Emulator will work since the server is running on the localhost.

What to do when ServerSocket throws IOException and keeping server running

Basically I want to create a rock solid server.
while (keepRunning.get()) {
try {
Socket clientSocket = serverSocket.accept();
... spawn a new thread to handle the client ...
} catch (IOException e) {
e.printStackTrace();
// NOW WHAT?
}
}
In the IOException block, what to do? Is the Server socket at fault so it need to be recreated? For example wait a few seconds and then
serverSocket = ServerSocketFactory.getDefault().createServerSocket(MY_PORT);
However if the server socket is still OK, then it is a pity to close it and kill all previously accepted connections that are still communicating.
EDIT: After some answers, here my attempt to deal with the IOException. Would the implementation be guaranteeing keeping the server up and only re-create server socket when only necessary?
while (keepRunning.get()) {
try {
Socket clientSocket = serverSocket.accept();
... spawn a new thread to handle the client ...
bindExceptionCounter = 0;
} catch (IOException e) {
e.printStackTrace();
recreateServerSocket();
}
}
private void recreateServerSocket() {
while (keepRunning) {
try {
logger.info("Try to re-create Server Socket");
ServerSocket socket = ServerSocketFactory.getDefault().createServerSocket(RateTableServer.RATE_EVENT_SERVER_PORT);
// No exception thrown, then use the new socket.
serverSocket = socket;
break;
} catch (BindException e) {
logger.info("BindException indicates that the server socket is still good.", e);
bindExceptionCounter++;
if (bindExceptionCounter < 5) {
break;
}
} catch (IOException e) {
logger.warn("Problem to re-create Server Socket", e);
e.printStackTrace();
try {
Thread.sleep(30000);
} catch (InterruptedException ie) {
logger.warn(ie);
}
}
}
}
If in doubt, you could try re-creating the server socket, using the same port. If the socket has been closed, then the creation will succeed and you can continue processing new connections. The old connections are gone, but that's outside of your control since the socket was closed. If the socket was not closed, then creating a new instance will fail since the port is still in use, which you can just ignore - i.e. don't replace the current server socket reference.
In general, clients should also assume that connections will be broken and that reconnection is necessary. In other words, it's not just the server that has to be robust - clients should also anticipate connection errors and reconnect.
You can get an IOException on an accept() if the server socket is closed (by you) or you run out of resources, e.g. file handles. Either way, there is not much you can do about it. If the serverSocket is closed (you can test for this) you probably had a good reason to do this. If you run out of resources, you will either have to increase your resource limit, which requires a restart of your application, or you have a resource leak.
Make sure you differentiate between different IOExceptions you might receive. Is it an exception on creating a connection? Is it an exception once a connection has already been established?
The only code you gave is for accept()ing. Generally speaking, an IOException usually means an error on any layer on the physical network.
Probably the best fallback behavior you can implement is to wait for a certain time quantum, and then try to reconnect. Assume you most possibly will not be able to reconnect, since you have lost network connection for more than a temporary period. Make sure you handle this gracefully. As #mdma mentioned, this must be supported by your clients as well.
However if the server socket is still
OK, then it is a pity to close it and
kill all previously accepted
connections that are still
communicating.
Please note that closing the server socket will NOT close previously accepted connections. As soon as a connection has been accepted it lives a separate, joyful life at a different port.

Java Socket Returns True

I hope you can help. Im fairly new to progamming and Im playing around with java Sockets.
The problem is the code below. for some reason commSocket = new Socket(hostName, portNumber); is returning true even when it has not connected with the server (server not implemented yet!). Any ideas regarding this situation?
For hostName Im passing my local machine IP and for port a manually selected port.
public void networkConnect(String hostName, int portNumber){
try {
networkConnected = false;
netMessage = "Attempting Connection";
NetworkMessage networkMessage = new NetworkMessage(networkConnected, netMessage);
commSocket = new Socket(hostName, portNumber);
// this returns true!!
System.out.println(commSocket.isConnected());
networkConnected = true;
netMessage = "Connected: ";
System.out.println("hellooo");
} catch (UnknownHostException e){
System.out.println(e.getMessage());
} catch (IOException e){
System.out.println(e.getMessage());
}
}
Many thanks.
EDIT: new Socket(.., ..); is blocking isnt it? i thought in that case if that was processed without exceptions then we have a true connection?
EDIT: I played around with anti virus and now it is working!
Had that exact same situation a few days ago on a corporate computer, and searched for it for hours.
Check your antivirus, some antivirus (like E*** N**32) use live TCP scanning that make a connection succeed even if nothing is listening on the target port but will reset it later when you try to read/write from the socket.
Add this to your code:
commSocket.getOutputStream().write(0);
commSocket.getInputStream().read();
If you get a SocketException now, you should really consider to change your antivirus.
Alternatively, set a breakpoint in your application right after creating the socket, and then use netstat -ano (on Windows) to check which process id is associated with the other endpoint of your socket (which should be on your machine if you connect to localhost).
I would suggest you to disable your antivirus, but in some cases even that does not help to unload their broken live TCP scanning driver...
The Socket constructor connects right away and will throw an IOException if it doesn't succeed. So apparently you have connected successfully to a server (this could be one you didn't make yourself).

Categories