Oreo: LocalOnlyHotspot is created, but socket exception happens - java

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.

Related

SocketException when there is no internet connection

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.
}
}

Android TCP socket not working

I'm trying to connect to a server running on my desktop with an Android app.
I tried making a desktop Java program to test the connection and it worked with this code:
Socket socket = new Socket(HOST, PORT);
BufferedReader in = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
System.out.println(in.readLine());
It instantly prints the server welcome message, and I can see a new connection on the server.
However, the same code running on Android (on a separate thread) can't make the connection and I end up with a socket timeout exception.
private class NetworkThread implements Runnable {
Socket socket;
#Override
public void run() {
try {
socket = new Socket(HOST, PORT);
BufferedReader in
= new BufferedReader(
new InputStreamReader(socket.getInputStream()));
textStatus.setText(in.readLine());
}catch (IOException ex){
Log.i("Network", ex.toString());
ex.printStackTrace();
}
}
}
The thread is created here
public void onConnectBtnClick(View view) {
new Thread(new NetworkThread()).start();
}
HOST is the IP of the server and PORT is the port and have the same values in the Java and Android clients.
I have opened the port in my firewall but the android app still can't make the connection, and I get
java.net.ConnectException: failed to connect to GPC/192.168.1.5 (port 399): connect failed: ETIMEDOUT (Connection timed out)
The manifest has the INTERNET and ACCESS_NETWORK_STATE permissions. What am I doing wrong?

can't connect Socket when not in same IP range. (subnet)

When running a ServerSocket on a machine A with ip 145.74.217.109
And then trying to connect to machine A using machine B with ip 145.74.219.103 I am unable to connect.
But when using machine C with ip 145.74.217.180 it works.
Iam not sure if this is solvable in code or its just network settings. If It is network issues is there another way to go around this problem or would I need to go away from sockets to ...?
Machine A:
public void run() {
try {
sock = new ServerSocket(Constants.PORT);
for (;;) {
Socket newsock = sock.accept();
System.out.println("Accepting new player: ");
new PaintballPlayer(newsock);
}
} catch (Exception e) {
System.out.println("IO error " + e);
}
System.out.println("End!");
try {
sock.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Machine B, C :
socket = new Socket(ip, Constants.PORT);
if you look at the IP us server has IP 145.74.217.109 IP with 145.74.217.180 are able to connect while 145.74.219.103 is not being able to connect it means subnet 145.74.219.X has no access to 145.74.217.X that is why it is not being able to connect. It is network setting ask you network administrator for that. Make your both machine have same subnet mask

WiFi network programming in android

i want to program a server/client app in android.
i have one server class on my pc and client on my android phone.
all permissions are ok.
Here is client:
try {
mysocket = new Socket("My PC IP Address", 4444);
} catch (UnknownHostException e) {...
} catch (IOException e) {...
}
here is server:
try {
myServerSocket = new ServerSocket(4444);
} catch (IOException e) {...
}
Socket clientSocket = null;
try {
clientSocket = serverSocket.accept();
System.out.println("Connection Established.");
} catch (IOException e) {
}
I uses "Connectify" program on my pc to have an (virtual)access point such that my phone connect to that.
But when I try to connect to server in my android app, it hangs and then throws Timed-out exception.
This code doesn't look bad.
Are you certain Connectify is working well?
You shoud try running both the server and the client you have built on your PC, using two different processes (as an example the server as a standalone and the client in the Android Emulator).
If it works properly from localhost to localhost:4444, the the connection is the cause of the problem, not your code. And otherwise, you will easily find the bug in your code.

Establishing a connection between Java server and client within Android appEDIT

I have an app in android in which I created an android client and a Java sever.
But I'm confronting the following issue: my client (the android part) connects to the local machine on port 6000 using the android loopback address.
My server (in Java) listens on local machine at the port 6000 - but what is the IP I have to use to get the socket that accepts the clients?
InetSocketAddress serverAddr = new InetSocketAddress(SERVERIP,serverPort);
serverSocket = new ServerSocket();
serverSocket.bind(serverAddr);
So what is the SERVERIP I have to use?
UPDATE:My client runns on an emulator!!!!!
EDIT:
public class ClientThread implements Runnable {
Object syncToken;
public ClientThread(Object syncToken) {
this.syncToken = syncToken;
}
public void run() {
try {
InetAddress serverAddr = InetAddress.getByName(serverIpAddress);
socket = new Socket(serverAddr, 50458);
} catch (UnknownHostException e) {
System.err.println("Don't know about host");
} catch (IOException e) {
System.err
.println("Couldn't get I/O for the connection to host");
}
try {
out = new PrintStream(socket.getOutputStream());
} catch (IOException e) {
System.out.println(e);
}
while (true) {
synchronized (syncToken) {
try {
syncToken.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
And here is: private String serverIpAddress = "10.0.2.2";!!!!!
From http://developer.android.com/guide/developing/devices/emulator.html#emulatornetworking: if you want to communicate from within the emulator to the local host, use IP 127.0.0.1 on the local host and use IP 10.0.2.2 in Android. This should let you communicate between the Android client and the local host server.
You want to run the server part on the Android? I guess not, and in such case using loopback address is not really going to work, as loopback interface on the Android system loops back to the Android machine itself, it is not routed to the outside.
For the serverAddr, use the #InetSocketAddress(int port) constructor, it specifies the wildcard address and a specific port, meaning it listens on all the interfaces of the machine.
Edit: For best results, on the android device use the DNS name of the server to connect to it.

Categories