I've been running a Socket.IO server (https://github.com/mrniko/netty-socketio) , communicating with a client (https://github.com/nkzawa/socket.io-client.java) that runs on an Android emulator. The emulator is hosted on the machine that runs the server. I was able to create the initial connection from the client to the server, and successfully send a message (client to server), but shortly after that the heartbeat failed and the connection was broken:
DEBUG [07:17:45.470] c.c.socketio.transport.NamespaceClient: Client
157e4f73-e26d-459c-ac1c-506628b66a09 for namespace has been
disconnected DEBUG [07:17:45.470]
c.c.socketio.SocketIOChannelInitializer: Client with sessionId:
157e4f73-e26d-459c-ac1c-506628b66a09 disconnected DEBUG
[07:17:45.470] c.c.socketio.transport.NamespaceClient: Client
157e4f73-e26d-459c-ac1c-506628b66a09 for namespace /android/ has been
disconnected DEBUG [07:17:45.471]
c.c.socketio.handler.ClientHead: 157e4f73-e26d-459c-ac1c-506628b66a09
removed due to ping timeout DEBUG [07:17:46.119]
c.c.s.transport.WebSocketTransport: Client with was already
disconnected. Channel closed!
Server code:
Configuration serverConfig = new Configuration();
serverConfig.setHostname(MACHINE_IP);
serverConfig.setPort(8082);
serverConfig.setPingTimeout(20);
SocketIOServer server = new SocketIOServer(serverConfig);
server.addNamespace("/android/")
server.start()
Client code:
IO.Options options = new IO.Options();
options.transports = new String[]{"websocket"};
options.reconnectionAttempts = 5;
options.reconnectionDelay = 10000;
Socket socket = IO.socket(MACHINE_IP + ":8082/android/", options)
What am I doing wrong?
Thanks.
I was finally able to resolve the problem myself (there may be other solutions as well).
What I did was:
Start the server on localhost - as it isn't necessary for it to be visible outside of the machine
Connect the client to 10.0.2.2 - which is the way for the emulator to access its host localhost
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've connected my Android phone to my laptop using Connectify.
I have a cherrypy web server running on 192.168.210.1:8080:
import cherrypy
class HelloWorld:
def index(self):
return "Hello world!"
index.exposed = True
cherrypy.quickstart(HelloWorld())
It works on my laptop, but when I try to put 192.168.1.8080 in my Android, there's no response and it keeps waiting indefinitely. I tried pinging to the IP from my phone, and it works, showing replies.
I also tried turning Windows Firewall off - it instanantly results in the message "Oops! Google Chrome could not connect to 192.168.210.1:8080". If I start it again, it's back to the previous state.
Please help.
You need to bind the socket on which the server is listen to '0.0.0.0', by default is bound to localhost, to do that just change the quickstart call, with this config:
config = {'global':
{'server.socket_host': '0.0.0.0'}
}
quickstart(HelloWorld(), config=config)
I am trying to implement a simple Android application that sends and recieves packets to and from a plugin written for Openfire server. The plugin is meant to recieve packets from a client for further processing. So it is not a chat. The following code snippet shows my way of sending packets to the server:
ConnectionConfiguration configuration = new ConnectionConfiguration(
HOST, PORT);
Connection connection = new XMPPConnection(configuration);
try {
connection.connect();
} catch (XMPPException e) {
e.printStackTrace();
}
if (connection.isConnected()) {
Packet packet = new Message();
packet.setFrom("123456789#localhost");
packet.setTo("987654321#component.localhost");
connection.sendPacket(packet);
connection.disconnect();
}
HOST and PORT are predefined constants.
I tried to use code in if clause inside the plugin and it worked perfectlly - component recieves packets and works with them. However, in my Android application this code does not work - packets do not reach the component.
So, guys, if you have any suggestions I will be greatful for your help. Maybe I use wrong technique somewhere - I am new to XMPP and Openfire.
Update
There are all needed permissions in application's manifest. And HOST is equal to a static IP address of the PC running Openfire server.
private static final String HOST = "192.168.1.100";
private static final int PORT = 5222;
In order to send packets to a server you should login to it using login() or loginAnonymously() methods of org.jivesoftware.smack.Connection class.
Thanks mr. Flow for the hint.
Connect and Disconnect
// Create the configuration for this new connection
ConnectionConfiguration config = new ConnectionConfiguration("jabber.org", 5222);
config.setCompressionEnabled(true);
config.setSASLAuthenticationEnabled(true);
Connection connection = new XMPPConnection(config);
// Connect to the server
connection.connect();
// Log into the server
connection.login("username", "password", "SomeResource");
....
// Disconnect from the server
connection.disconnect();
</code>
you should login first, here is the guide to manage connections http://www.igniterealtime.org/builds/smack/docs/latest/documentation/connections.html
in my app i want to receive some message form the server and based on that i want to display pop up message and for this i want to do socket communication in android.
When i am try to read response form the server using socket.getInputstream i will get error
"request time out :Address family not supported by the protocol"
Here is my code.
Socket socket = new Socket("localhost",62000));
boolean isconnect = socket.isConnected();
Log.e("Socket Connection ", String.valueOf(isconnect));
// Read and display the response message sent by server application
//
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
String message = (String) ois.readObject();
System.out.println("Message: " + message);
ois.close();
socket.close();
Unfortunately, this exception is caught and reported by Android, and your app doesn't get to see the stacktrace as far as I know (and it's reported at the debug level).
I'm pretty sure the cause of this exception is that an outside machine is trying to access Android and the port is closed (so the connection is refused).
Make sure:
You have a server running on the right port in Android
You turn on port forwarding for that port (e.g. you can have the service running on port 10000 in the Android emulator, and have your computer's port 20000 forward to that port)
Your client is accessing Android using 0.0.0.0 via the forwarded port (20000, not 10000)
You correctly specify TCP or UDP (might break things if it's the wrong one)
Hope this helps!
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.