I have few question regarding Socket Communication in Android.
1)I have developed server socket app for android that listens to port 8888.
a) When i host my server on the emulator I'm unable to communicate to it through Client application that I have on my PC since both (Emulator & Client) app are on my laptop & on the same network i think that they should be able to communicate with each other.
b) When i deploy the same server app on my android mobile device and try to communicate it through the same Client Application that I have on my PC, the client application gives a timeout exception as its unable to communicate to it.
My first question is How can i test server/client socket app with Emulator & 1 android device? Can i even use my PC's client socket application to test my server socket?
**I have Client Socket Application for my other application so theres no problem with the client application.
2) My second question is to test my server app on the android device do I have to forward the desired port?
a) For Emulator: How can I forward port?
b) For Device: How can i forward port?
c) Can i forward port programmatically?
**Just for Information:
I'm using Eclipse as android developement tool.
** MY Server Code as there can also be problem with my server socket code too.
Socket socket = null;
DataInputStream dataInputStream = null;
DataOutputStream dataOutputStream = null;
ServerSocket serverSocket = null;
try
{
serverSocket = new ServerSocket(SERVERPORT);
System.out.println("Listening :" + SERVERPORT);
System.out.println("Server IP:" + SERVERIP);
}
catch (Exception e)
{
e.printStackTrace();
}
while(true)
{
try
{
socket = serverSocket.accept();
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
System.out.println("ip: " + socket.getInetAddress());
String str = in.readLine();
System.out.println("message Received: " + str);
}
catch (Exception e)
{
e.printStackTrace();
}
finally
{
if( socket!= null)
{
try
{
socket.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
if( dataInputStream!= null)
{
try
{
dataInputStream.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
if( dataOutputStream!= null)
{
try
{
dataOutputStream.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
}
Edited:
A very interesting part is that if i set port to 8080 PC's Client Socket App do connect to Android App on my android device but i don't receive socket on my server nor the data I send. Nothing happens after the link => socket = serversocket.accept();
Also I have set the permission in the manifest.
have you set the right permission inside your Manifest.xml?
<uses-permission android:name="android.permission.INTERNET" />
is needet to setup sockets
For your first question, on how to access the network from the emulator: the emulator runs on its own network address space, isolated from your PC. You have to configure network redirection to access devices on your network.
See more details in https://developer.android.com/studio/run/emulator-networking.html
Thanks to the question and answers. It helps me figure out the narrow path towards my working combination.
The procedure turned out to be trickier than we expected. The socket client side has to use "127.0.0.1", instead of "192.168.0.15" or "10.0.2.15", to connect to the Android emulator on the same computer. The following are 6 steps I tried and works.
Step 0: Go to terminal
Step 1: find out port of Android emulator console using adb, Android Debug Bridge (in my case the port is 5554)
/Users/zhijunsheng/Library/Android/sdk/platform-tools/adb devices
List of devices attached
9357cefb device
emulator-5554 device
Step 2: retrieve auth_token of Android emulator console
cat /Users/<my_home_dir>/.emulator_console_auth_token
sncfmfC+Lg9OtAT4
Step 3: connect to Android emulator console
telnet localhost 5554
Trying ::1...
Connected to localhost.
OK
Step 4: authenticate
auth sncfmfC+Lg9OtAT4
Step 5: add the redirection instruction
redir add tcp:50000:50001
I also have a video in YouTube recording what I tried.
Related
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.
I have created an Android application that has two input fields and a verify button. I want to send information to a SQL Express server that is on my Windows desktop over UDP connection. I have tested the connection with a utility and it works perfect but when I connect to the server, I don't know where the default location is for the information to be stored. Can anyone please help me? Below is the UDP connection code.
int port = 48569;
try {
DatagramSocket s = new DatagramSocket();
InetAddress local = InetAddress.getByName("10.3.22.218");
int msg_length = msg.length();
byte[] message = msg.getBytes();
DatagramPacket p = new DatagramPacket(message, msg_length, local, port);
s.send(p);
}catch (SocketException e) {
e.printStackTrace();
}catch (UnknownHostException e) {
e.printStackTrace();
}catch(IOException e) {
e.printStackTrace();
}
SQL Server on your desktop does not listen for UDP packets. Information sent with these packages will not be stored anywhere. To connect to SQL Server you will need a client (ADO.NET). Sending packages over the wire will not work. And why UDP? How you will get back the result from the "verification"?
And I believe connecting directly from your mobile app to the SQL Server is not the best option. You should either create some service layer over your database (for example WCF service) and use this API from your mobile app, or go further and look for Azure Mobile App Service or something similar.
So , the flow of the application is ,
first , I use my android phone to connect a device (which is a server) through wifi, then , I would like to send a string to that device, and that is all.
The problem is , when I try to send like this
new Thread(new Runnable() {
#Override
public void run() {
try {
Socket socket = new Socket("192.168.8.101",2001);
DataOutputStream DOS = new DataOutputStream(socket.getOutputStream());
DOS.writeUTF("61");
socket.close();
} catch (Exception e) {
final String error = e.getMessage();
runOnUiThread(new Runnable(){
#Override
public void run() {
Toast.makeText(mContext, error, Toast.LENGTH_SHORT).show();
}
});
Log.d("test1",e.getMessage());
e.printStackTrace();
}
}).start();
it return the failed to connect to /192.168.8.101 (port 2001) : connect failed EHOSTUNREACH (No route to host) in the exception
How to fix that , and by programming or using some way , are there any way to check whether the ip and port is correct ? Thanks
Make sure you turn off the firewalls on that port.
To make sure IP is up we usually ping that machine.
There is a tool called wireshark that taps the packets coming to your machine. So put you send function in while 1000 loop and pump messages. Turn wiresahrak at the server and see if you are able to get the packets there.
There are lots of other programs which can connects to sockets. take a sample java program and try to get connected to the other socket. If it does, your android stuff will also do.
Check your router's security configurations. I had the same problem, then I turned off the option "Client Isolation" in my router's Wireless configuration and it worked.
I've written a small file transfer program for android using standard Java sockets. The program works fine except for the following case:
I connect two android devices A and B over WiFi tethering connection. Device A is sharing the connection (enabled as wireless hotspot). When I run java server on A and client on B, the program works okay but when I run the server on device B, it can't accept any socket binding request from A. It doesn't throw any exception. Seems like the request is not reaching the server! However, both the devices are connected (ping test is okay in both directions). Can't I run socket server on a device connected as hotspot client? I thought once the networking is setup correctly, the application would work in any direction.
Also, Wireshark traces reveal nothing. What am I missing here? Please help! Here are my code snippets:
Server side (waiting for client connection):
while (true) {
try {
socket = serversocket.accept();
Runnable connectionHandler = new ConnectionHandler(
socket, fileArray, filepathNameArray,
SenderActivity.this, userID, handler);
new Thread(connectionHandler).start();
userID = userID + 1;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
I would appreciate any kind of help! Thanks in advance.
could you please advice how to connect to development machine from device?
I can easily do this from Emulator, but from device I have connection timeout exception.
Here is my code:
String hostname = "10.0.2.2";
int port = 4444;
Socket socket = null;
try{
socket = new Socket(InetAddress.getByName(hostname), port);
} catch(UnknownHostException e) {
Log.e("Capturer","UnknownHostException : " + e.getMessage(), e);
} catch(IOException e) {
Log.e("Capturer", "IOException : " + e.getMessage(), e);
}
Once you are on your device, you must use the actual (external visible) ipaddress/hostname for your development machine. If you connect via wifi with your device you should be able to use an internal(to your network) network ip address, if you are on 3g or edge, you will need your external, publicly visible ip address, if you have a network this will only get your to your modem/router, and you will need to setup the correct port forwarding for this to work.
If you are just trying to send data from the device to the development machine for development purposes, you could also look into adb. In particular, check out adb forward. This would allow you to send data over the USB connection.