Working on a client-server android application. The clients are polling the bufferedinputstream (in) for server messages, meanwhile also repeatedly checking if server is reachable so they can terminate instantly when server goes offline.
try {
while (true) {
if (MainActivity.in.available() > 0) {
message = MainActivity.readInput();
break;
}
Thread.sleep(100);
}
} catch (IOException e) {Log.e("myoutput", e.toString()); serverOffline = true; } //server probably offline?
catch (InterruptedException e2) {}
On one of my test devices (android 2.2) this works as I thought, as soon as I close down the server the IOException is triggered. Although on my second test device (android 4.3) the IOException is not triggered (compling with API 8). But I'm starting to think this is not a device thing as I tried running both API 8 and 18 in the emulator and it didn't trigger.
Any ideas?
I'm probably not providing all essential information to get any help from here, please let me know if so and I'll provide!
Related
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)
I'm writing an Android app to communicate with a Windows service over socket connections.
The code is working but I want to add the ability to detect devices connected on local network so the app can determine which computer is running the windows service I want, I'm using the code below which I got from this website too. My issue is the code below only detects android devices and doesn't detect my laptop. I can ping my device from my laptop and ping my laptop from my device, so what to do from here?
public void checkHosts(String subnet) {
int timeout = 1000;
for (int i = 1; i < 254; i++) {
String host = subnet + "." + i;
try {
if (InetAddress.getByName(host).isReachable(timeout)) {
System.out.println(host + " is reachable");
System.out.println("Host Name: "
+ InetAddress.getByName(host).getHostName());
}
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
InetAddress.isReachable() is not very reliable.
If ICMP messages are blocked you won't get an answer.
What you could do is sending a broadcast message.
Your server application has to listen for this message and answer it.
This way you get the server IP address and you can connect to it.
And you have to send only one message to reach all hosts in the subnet.
Example code for sending and receiving broadcast messages
Thank you everyone I ended up creating a socket connection to each IP in the network and displaying host name from the socket. it showed me all devices whether they are android devices or windows machines.
Of course since I made the socket listen at port 8000 on both device and computer, so using a socket will give result IF AND ONLY IF both ends are listening on the same port, and I only care about computers that are running my service.
I really appreciate all the suggestions and help :)
I do only have this problem with an outgoing connection. I coppied most parts of my sourcecode from the example http://developer.android.com/guide/topics/wireless/bluetooth.html
Therefore I don´t really know whats the cause of this problem is...
First of all the code where the IOException occures:
try {
// This is a blocking call and will only return on a
// successful connection or an exception
socket = mmServerSocket.accept();
} catch (IOException e) {
Log.e(TAG, "Socket Type: " + mSocketType + "accept() failed", e);
break;
}
Every time I connect my phone to my tablet accept() throws an IOException on my phone:
BluetoothChatService Socket Type: nullaccept() failed
BluetoothChatService java.io.IOException: Operation Canceled
I believe this is somehow related to the problem that is described in this blog:
http://www.androiddiscuss.com/1-android-discuss/86844.html
By the way the BluetoothConnection works well, but my phone can´t receive any data.
Edit: I have just realized that a bluetooth connection from my Galaxy S to my Motorola Xoom could not be established with other popular bluetooth apps from the market...
If I connect the other way round, from my tablet to my phone, the tablet just reboots completely.
It could be an authentication issue. Are your devices paired?
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.
I have a simple JMS application deployed on OC4J under AIX server, in my application I'm listening to some queues and sending to other queues on a Websphere MQ deployed under AS400 server.
The problem is that my connections to these queues are terminated/closed when it stays idle for some time with the error MQJMS1016 (this is not the problem), and when that happens I attempt to recover the connection and it works, however, the old connection is stuck at the MQ and would not terminate until it is terminated manually.
The recovery code goes as follows:
public void recover() {
cleanup();
init();
}
public void cleanup(){
if (session != null) {
try {
session .close();
} catch (JMSException e) {
}
}
if (connection != null) {
try {
connection.close();
} catch (JMSException e) {
}
}
}
public void init(){
// typical initialization of the connection, session and queue...
}
The MQJMS1016 is an internal error and indicates that the connection loss is due to something wrong with the code or WMQ itself. Tuning the channels will help but you really need to get to the problem of why the app is spewing orphaned connections fast enough to exhaust all available channels.
The first thing I'd want to do is check the versions of WMQ and of the WMQ client that are running. If this is new development, be sure you are using the WMQ v7 client because v6 is end-of-life as of Sept 2011. The v7 client works with v6 QMgrs until you are able to upgrade that as well. Once you get to v7 client and QMgr, there are quite a bit of channel tuning and reconnection options available to you.
The WMQ v7 client download is here: http://bit.ly/bXM0q3
Also, note that the reconnect logic in the code above does not sleep between attempts. If a client throws connection requests at a high rate of speed, it can overload the WMQ listener and execute a very effective DOS attack. Recommended to sleep a few seconds between attempts.
Finally, please, PLEASE print the linked exceptions in your JMSException catch blocks. If you have a problem with a JMS transport provider, the JMS Linked Exception will contain any low-level error info. In the case of WMQ it contains the Reason Code such as 2035 MQRC_AUTHORIZATION_ERROR or 2033 MQRC_NO_MSG_AVAILABLE. Here's an example:
try {
.
. code that might throw a JMSException
.
} catch (JMSException je) {
System.err.println("caught "+je);
Exception e = je.getLinkedException();
if (e != null) {
System.err.println("linked exception: "+e);
} else {
System.err.println("No linked exception found.");
}
}
If you get an error at 2am some night, your WMQ administrator will thank you for the linked exceptions.
Since the orphaned connections (stuck connections on MQ side) does not affect the messages processing (i.e. they do not consume messages), we left things as it is until the maximum connections allowed on the MQ was reached.
The recovery did not work anymore, and once we reached that point, the MQ administrator had to clean the orphaned connection manually, however, the good news is that searching for this particular problem led to an issue reported on IBM support site:
check here