SocketException when there is no internet connection - java

I'm programming an application which opens socket in service and sends some data to server and also listens for incoming data. Problem of course appears when connection with internet is lost on android device.
Here is code snippet where i get
java.net.SocketException: recvfrom failed: ETIMEDOUT (Connection timed
out)
try{
mSocket = new Socket("xxx.xxx.xxx.xxx", xxxxx);
out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(mSocket.getOutputStream())), true);
BufferedReader in = new BufferedReader(new InputStreamReader(mSocket.getInputStream()));
String s;
while((s = in.readLine())!= null){ //here error of course
...
}
mSocket.close();
}catch(Exception e){
e.printStackTrace();
}
Error is thrown when internet connection is lost and BufferedReader try to
readLine(). How to avoid this and why is it of course?
UPDATE
Error didn't bother me until I tryed to do next scenario:
1) run socket with wifi turned on
2) turn on also mobile data
3) turned off wifi
When wifi is turned off error occourse, but i'm connected to internet through mobile data, so I would like continu to listen on socket without error. Is this possible and how?

What you should do is reconnect a new socket in your catch block. The original connection is now gone, and I don't know a way of "seamlessly" swapping it.
try {
mSocket = new Socket("xxx.xxx.xxx.xxx", xxxxx);
...
} catch(Exception e){
try {
mSocket = new Socket("xxx.xxx.xxx.xxx", xxxxx);
...
} catch (Exception e2) {
// OK you really lost connectivity at this point, tell the user.
}
}

Related

Oreo: LocalOnlyHotspot is created, but socket exception happens

I am creating some testing app, and I need to connect several devices via Wi-Fi direct. On Android 8 the only way to do it is to create LocalOnlyHotspot. I have done it successfully, devices are connecting. However I need to transfer some strings between devices. For those reason I have made in separate threads
-> on server side
try{
int port = 9802;
ServerSocket serverSocket = new ServerSocket(port);
running = true;
while (running){
Socket socket = serverSocket.accept();
}
} catch (IOException e) { e.printStackTrace(); }
-> on client side
Socket socket = null;
try{
socket = new Socket(address, port);
} catch (IOException e) { e.printStackTrace(); }
I am always getting an exception on client's side
failed to connect to /192.168.43.1 (port 9802) from /:: (port 33044): connect failed: ECONNABORTED (Software caused connection abort)
As I have googled the reason is that the network has no internet connection.
How can I solve this problem? Is any other way to pass strings between 2 devices on Android 8 using Wi-Fi direct?
Thanks in advance.

Android,Java,socket, determine remote host disconnect

I'm trying to code a TCP client in android java. Most works fine. But i have one issue. If the socket is connected and the remeote host shuts down or the network goes down or something else, the socket.getinputstream keeps blocking.
I don't know if the socket is still connected. I code in objective-c too and in objective-c i get an event that the socket forcefully shuts down and i can try to reconnect. So on objective c the socket tracks the state.
In java the socket and the inputstream is still connected or blocked even the socket is down. How can i check if the socket is still connected?
#Override
protected Void doInBackground(String... params) {
try {
String host = params[0];
int port = Integer.parseInt(params[1]);
SocketAddress sockaddr = new InetSocketAddress(host, port);
Socket socket = new Socket();
socket.connect(sockaddr,5000);
socket.setSoTimeout(7000);
out = new PrintWriter(socket.getOutputStream(), true);
mBufferIn = new BufferedReader(new InputStreamReader(socket.getInputStream()));
while (mRun) {
try {
-----> mServerMessage = mBufferIn.readLine();
}catch (Exception e){
Log.d("my","hier3" + e.getMessage());
}
if (mServerMessage.trim() != null) {
sender.messageReceived(s2);
}else{
}
}
}
} catch (UnknownHostException e
) {
The question of how to detect if the remote peer/socket has closed the connection has been answered here as well as here.
Basically, the answers suggest that you attempt to read from the socket, and then observe what happens (read() returns -1, or readLine() returns null or your read methods raise EOFException.

Simple socket communication program is not working at all

Server accepts multiple connections using threads.
Server:
#Override
public void run () {
try {
System.out.println(client);
System.out.println("Client Connected");
//So far, so good. Client is connected
BufferedReader in = new BufferedReader(
new InputStreamReader(this.client.getInputStream()));
System.out.println(in.readLine());
// Nothing happens
} catch (Exception e) {
e.printStackTrace();
}
}
Client:
try {
PrintWriter out = new PrintWriter(Client.socket.getOutputStream());
BufferedReader in = new BufferedReader (
new InputStreamReader(Client.socket.getInputStream()));
out.write("Information sent from client");
// Does not work
in.read();
// Before this .read it would give a "Connection reset" probably
// Because the client closed before the server could even read
}
No error, but it just hangs, nothing is being sent. Firewall is down so it can't be that. Also it used to work yesterday. I have no idea what I could have messed up.
write writes the content only to the InputStream. Use println to send an additional newline character to correspond to the readLine statement on the server.
out.println("Information sent from client");

Java listen for server - messages getting lost

I am using a thread and a while true loop to listen for message from my server. For some strange reason some messages are getting lost. (I am logging from my server so i am 100% sure that the message is sent, therefore the problem has to be on the client side). This seems to happend when the server is sending messages fast to the client.
Im using the following code to listen for new messages (on my client):
Socket socket;
try {
socket = new Socket(InetAddress.getByName("url.com"), 8080);
is = new DataInputStream(socket.getInputStream());
os = new DataOutputStream(socket.getOutputStream());
} catch (IOException ex) {
Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
JOptionPane.showMessageDialog(rootPane,
"Could not establish network connection to the server."
+ " \nPlease check your internet connection and restart the application.",
"Unable to connect",
JOptionPane.INFORMATION_MESSAGE);
WindowEvent wev = new WindowEvent(this, WindowEvent.WINDOW_CLOSING);
Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(wev);
setVisible(false);
dispose();
System.exit(0);
}
// Starta thread to listen for messages from the server
new ListenFromServer().start();
/*
* Thread class to listen for message from the server
*/
class ListenFromServer extends Thread {
public void run() {
while (true) {
try {
BufferedReader in = new BufferedReader(new InputStreamReader(is));
String tmpMsg = in.readLine().replaceAll("\\r\\n|\\r|\\n", "");
JSONObject json = new JSONObject(tmpMsg);
if(json.get("type").toString().contains("preview")) {
System.out.println("PREVIEW: " + json.get("msg").toString());
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
You shouldn't be creating a new BufferedReader to receive each message. If two messages arrive in quick succession, it could pull multiple messages out of is, and then you're discarding the contents. Declare in outside of your while loop (and handle the close condition appropriately).
I think what you want is a ServerSocket -- it listens and handles a queue of incoming connections (default size 50) so that you don't lose connections. As your code is, if a connection is attempted in the time between one connection getting established and the loop coming around to connect() again, there wouldn't be anything listening.

Simple Client Server communication

I am learning currently about client server communication using Java through sockets.
First of all I retrieve my own machine's IP Address using following code.
InetAddress ownIP=InetAddress.getLocalHost();
//the result being 192.168.56.1
Now I write the simple client server application using the above mentioned address as follow
public class SimpleClientServer {
public static void main(String[] args)
{
//sending "Hello World" to the server
Socket clientSocket = null;
PrintWriter out = null;
BufferedReader in = null;
try
{
clientSocket = new Socket("192.168.56.1", 16000);
out = new PrintWriter(clientSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(
clientSocket.getInputStream()));
out.println("Hello World");
out.close();
in.close();
clientSocket.close();
}
catch(IOException e)
{
System.err.println("Error occured " + e);
}
}
}
The result hower reads a follow.
Error occured java.net.ConnectException: Connection refused: connect
What is the reason for this. Is it just the wrong host address?
From the code you have given you seem to suggest that there is currently nothing listening on port 16000 for the socket to connect to.
If this is the case you need to implement something like
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(16000);
}
catch (IOException e) {
System.err.println("Could not listen on port: 16000.");
System.exit(1);
}
More information can be found in the Java online documentation and a full example is included.
With sockets, no matter what language you're using, you either initiate a connection with socket_connect or you listen and accept with socket_listen and socket_accept. Your socket_connect call is trying to connect to an ip address that doesn't seem to be listening to anything.

Categories