Socket connection between two emulators - android

I want to connect two Android emulators (both running on the same host) with sockets.
I have a server running on one of them and listening to the 7000 port on the external IP address:
InetAddress addr = InetAddress.getByName("10.0.2.15");
ServerSocket serverSocket = new ServerSocket(7000, 50, addr);
try {
sock = serverSocket.accept();
} finally {
serverSocket.close();
}
and a client on a different emulator on the same host connecting to that port:
socket = new Socket();
socket.bind(new InetSocketAddress("10.0.2.15", 6666));
socket.connect(new InetSocketAddress("10.0.2.2", 7000));
I have bound the client to the 6666 port so I can do the adb port forwarding necessary:
(host) .\adb.exe forward --list
emulator-5554 tcp:7000 tcp:7000
emulator-5556 tcp:6666 tcp:6666
I can see with the debugger that the client socket is in "connected" state, but calling:
dataInputStream = new DataInputStream(socket.getInputStream());
dataInputStream.available(); // this throws IOException Broken Pipe
throws an IOException of Broken Pipe.
Any ideas where the problem is?

Using redir instead of adb forward seems to solve the problem.
On the server emulator
telnet locahost 5554
redir add tcp:7000:7000
On the client emulator
telnet localhost 5556
redir add tcp:6666:6666
I don't really understand why there is a difference, as the documentation states:
"The Android Debug Bridge (adb) tool provides port forwarding, an alternate way for you to set up network redirection."

Related

Dart/Flutter sockets connects on random port

Modern programming is turning more and more frustrating. Trying to do a simple socket test app on Flutter (tested on Android). Code is simple and self explanatory:
void Connect()
{
print("connecting...");
Socket.connect("localhost", 80).then((Socket sock) {
socket = sock;
socket?.listen(dataHandler,
onError: errorHandler,
onDone: doneHandler,
cancelOnError: false);
socket?.write("GET / HTTP/1.1");
}).catchError((Object e) {
print("Unable to connect: $e");
});
}
Code throws exception. Output:
I/flutter (15930): connecting...
I/flutter (15930): Unable to connect: SocketException: OS Error: Connection refused, errno = 111, address = localhost, port = 47244
The port is always different, why TF is that happening?
The port number in the error message is the local port and not the remote port. There are an issue about this problem here: https://github.com/dart-lang/sdk/issues/12693
In short, when connecting using TCP, you need two ports. One local which is open on your device and one remote which is the port open on the system you are trying to call. After a connection is established, the communication is going between this two port numbers.
So the error indicates that your server running on localhost:80 is refusing the connection from your application. The local port number in the error message can often just be ignored since it is not really relevant to debug most issues.

Error sending socket [WinError 10061]No connection could be made because the target machine actively refused it for Socket from Python to Android

I am sending a socket from a python script to my android phone and vice versa. When my android sends a packet to my python script it works but sending packets from python script to android gives this error:
Error sending socket [WinError 10061]
No connection could be made because the target machine actively refused it
Note: When sending from android to python the function uses a different socket and different port. The error occurs here s.connect((host, port))
Here is my python code to send the packet:
try:
s = socket.socket()
host = "ip_address_of_android"
port = 7801
s.connect((host, port))
print("connected")
s.listen(5)
print("sending")
text = "hello"
s.sendall(text.encode())
s.close()
except Exception as e:
print("Error sending socket ", e)
And here is my android studio code to receive the packet:
public String receives() {
Socket socket;
DataInputStream ds;
try {
socket = new Socket("ip_address_of_android", 7801);
ds = new DataInputStream(socket.getInputStream());
boolean done = false;
while (!done) {
result = ds.readUTF();
}
} catch (Exception e) {
System.out.print("error");
}
return result;
}
I am assuming it is an android firewall error but I have no idea how to fix this. Thanks in advance.
It is not an Android firewall error.
Your code has mixed together the client & server logic in a nonsensical way.
The server (Android) should listen() and accept().
The client (Python) should connect(). It should not listen().
"Target machine actively refused it" indicates that the client successfully reached the server's network interface, but the server OS said, "no-one has port 7801 open, so there's nothing for me to connect you to." The Android side never opened 7801, because it never listen()-ed.

Android Server Socket

I am unable to reach the Android Server on the emulator from a program on my desktop, how do I solve it?
Some code (from How to find LAN ip address of android device?):
public static ArrayList<String> getSelfIP(){
try {
ArrayList<String> ipList = new ArrayList<>();
for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) {
NetworkInterface intf = en.nextElement();
for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) {
InetAddress inetAddress = enumIpAddr.nextElement();
if (!inetAddress.isLoopbackAddress()) {
ipList.add(inetAddress.getHostAddress().toString());
}
}
}
return ipList;
} catch (SocketException ex) {}
return null;
}
The result is [fe80::5054:ff:fe12:3456%eth0, 10.0.2.15]
What do I have to configure or do to make the emulator reachable by my desktop programs?
I have done the following:
> adb forward tcp:50000 tcp:50000
However, I am unable to access the server through localhost:50000.
Try using the ip address 10.0.2.2.
It is the Special alias to your host loopback interface (i.e., 127.0.0.1 on your development machine)
Take a look at this Android documentation, Section "Using Network Redirection".
Setting up Redirection through the Emulator Console
Each emulator instance provides a control console the you can connect
to, to issue commands that are specific to that instance. You can use
the redir console command to set up redirection as needed for an
emulator instance.
First, determine the console port number for the target emulator
instance. For example, the console port number for the first emulator
instance launched is 5554. Next, connect to the console of the target
emulator instance, specifying its console port number, as follows:
telnet localhost 5554
Once connected, use the redir command to work
with redirection. To add a redirection, use:
add <protocol>:<host-port>:<guest-port>
where <protocol> is either tcp
or udp, and <host-port> and <guest-port> sets the mapping between your
own machine and the emulated system, respectively.
For example, the following command sets up a redirection that handles
all incoming TCP connections to your host (development) machine on
127.0.0.1:5000 and will pass them through to the emulated system's 10.0.2.15:6000:
redir add tcp:5000:6000
In your case the last command would be
redir add tcp:5000:5000
I had this issue once, use 10.0.2.2 IP adress it should solve your problem.

Is it possible to establish a Bluetooth connection with a Java/Android client and Python server?

I am trying to make a bluetooth connection with my Android client and a Python server. However, I am unable to do so since my Android client always fails to connect. Now I am wondering whether it is possible at all to use an Android Bluetooth socket and a python socket together. Is that possible?
And if so, do you have suggestions what else I might try? In a nutshell, this is what I do:
My Android client:
I get a Bluetooth device like this:
BluetoothDevice device = BluetoothAdapter.getDefaultAdapter().
getRemoteDevice(deviceAddress);
Where deviceAddress is equal to the bluetooth MAC address of my laptops bluetooth adapter. Which is E0:F8:47:3F:80:49
Then I use that device to create a Socket:
BluetoothSocket socket = device.createRfcommSocketToServiceRecord(MY_UUID);
Where MY_UUID is this string: 00001101-0000-1000-8000-00805F9B34FB
After that I just call connect:
socket.connect();
And that is where it fails to connect. Maybe it is because of server wihich looks like this:
My Python server:
import bluetooth
hostMACAddress = 'E0:F8:47:3F:80:49' # The MAC address of a Bluetooth adapter
port = 3
backlog = 1
size = 1024
s = bluetooth.BluetoothSocket(bluetooth.RFCOMM)
s.bind((hostMACAddress, port))
s.listen(backlog)
try:
client, clientInfo = s.accept()
while 1:
data = client.recv(size)
if data:
print(data)
client.send(data) # Echo back to client
except:
print("Closing socket")
client.close()
s.close()

Can't use ServerSocket on Android

I'm trying to listen on a port using ServerSocket on an Android device. I want to be able to connect to this port over WiFi using a computer on the same network.
I get no exception when binding it to a port, however when I check netstat it says:
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 (null):4040 (null):* LISTEN
I've tried countless ways of binding it to localhost, 0.0.0.0, the WiFi LAN IP address of the device with SocketInetAddress and InetAddress.getByName. Nothing seems to work.
When I try to connect to the port from a computer in the same WiFi (I've tried both netcat and Java's Socket.connect()), all I can see in Wireshark is an ARP request:
Who has [phone's LAN address]? Tell [computer LAN address].
This request repeat itself until timed out.
I've tried the reverse way, by setting the ServerSocket on the computer and connecting to that port from the phone, that works very well.
My testing phone is an Samsung Spica i5700 with a custom ROM.
Any ideas?
Edit:
The code is simple as this:
ServerSocket server = new ServerSocket();
server.setReuseAddr(true);
server.setTimeout(0);
server.bind(new InetSocketAddress(4040));
Socket client = null;
while((client = server.accept()) == null);
// Connected
enter code here
enter code here
Instead of using server.bind, try initializing the server socket like this:
server = new ServerSocket(4040);
Also, server.accept() will actually block until a connection is made, so you don't need that while loop (see: http://download.oracle.com/javase/1.5.0/docs/api/java/net/ServerSocket.html#accept() )
I struggled with this too and was only able to connect to my Android server by using:
ServerSocket myServerSocket = new ServerSocket();
String hostname = getLocalIpAddress();
myServerSocket.bind(new InetSocketAddress(hostname, myPort));
Where hostname was the local IP, which I got using the getLocalIpAddress() function from this page:
https://github.com/Teaonly/android-eye/blob/master/src/teaonly/droideye/MainActivity.java
I was able to get this working by using
ServerSocket server = new ServerSocket( myTcpPort, 0, addr );
where addr = InetAddress of your phone. Otherwise, it only seems to bind to localhost (127.0.0.1). Also, I'm using port 8080.

Categories

Resources