I have trouble with connecting to a local web interface (192.168.10.13:3671) that are connected to my KNX network from the emulator/phone in Android Studio.
I've tried to connect to the same web interface with a already developed app called KNXwizard and that works, but I see in the code that that app uses AsyncTask.
Always getting this error: Error creating KNXnet/IP tunneling link: tuwien.auto.calimero.KNXException: connecting from /192.168.163.198:3671 to /192.168.10.13:3671: socket failed: EPERM (Operation not permitted)
I've checked this posts
Socket failed 1
Socket failed 2
Tried everything there, added permissions to my AndroidManifest.xml, uninstalled, used physical phone etc. But nothing works.
It could be my code, I've tried searching for an alternative method for AsyncTask. So it could be that the code is written wrong. Hope someone could help me out.
MainActivity:
public class MainActivity extends AppCompatActivity {
private static InetSocketAddress local = new InetSocketAddress("192.168.163.198", 3671);
private static InetSocketAddress server = new InetSocketAddress("192.168.10.13",
KNXnetIPConnection.DEFAULT_PORT);
Button btn;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn = (Button)findViewById(R.id.button);
ExecutorService executorService = Executors.newSingleThreadExecutor();
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
executorService.execute(new Runnable() {
#Override
public void run() {
//doInBackground
System.out.println("This example establishes a tunneling connection to the KNXnet/IP server " + server);
// A KNX tunneling link supports NAT (Network Address Translation) if required.
// We also indicate that the KNX installation uses twisted-pair (TP) medium, with TP1 being the most common.
// KNXNetworkLink is the base interface implemented by all supported Calimero links to a KNX network.
try (KNXNetworkLink knxLink = KNXNetworkLinkIP.newTunnelingLink(local, server, false, TPSettings.TP1)) {
System.out.println("Connection established to server " + knxLink.getName());
System.out.println("Close connection again");
} catch (KNXException | InterruptedException e) {
// KNXException: all Calimero-specific checked exceptions are subtypes of KNXException
// InterruptedException: longer tasks that might block are interruptible, e.g., connection procedures. In
// such case, an instance of InterruptedException is thrown.
// If a task got interrupted, Calimero will clean up its internal state and resources accordingly.
// Any deviation of such behavior, e.g., where not feasible, is documented in the Calimero API.
System.out.println("Error creating KNXnet/IP tunneling link: " + e);
}
}
});
}
});
}
I figured it out.
It was a stupid mistake with the IP address, should have seen that before. I just change the IP address to that I have on the phone I was connected to (192.168.10.15).
Related
I set up a very basic node.js server with the following code:
const express = require("express");
const app = express();
const port = 8000;
const ip = '192.16x.xxx.yyy'; // the x's and y's are placeholders. I didnt want to write my real IP here
const http = require("http").createServer();
const io = require("socket.io")(http);
// using the socket, we can send/receive data to/from the client
// the server listens for the "connection" event
io.on("connection", (socket) => {
// emit an event called "welcome" with a string as data to the client using its socket
// so, whenever the client connects to the server, it receives this welcome message
socket.emit("welcome", "Hello and Welcome to the Socket.io server.");
console.log("a new client is connected.")
});
// the server listens on the specified port for incoming events
http.listen(port, ip, () => {
console.log("Server is listening on " + ip + ":" + port);
});
So, the server is listening for the "connection" event and sends a welcome message when a client connects to the server.
The client which is an Android app looks like this:
import com.github.nkzawa.socketio.client.IO;
import com.github.nkzawa.socketio.client.Socket;
import com.github.nkzawa.emitter.Emitter;
import java.net.URISyntaxException;
public class MainActivity extends AppCompatActivity {
private Socket mSocket;
private TextView mTextView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextView = findViewById(R.id.textView);
try {
/*
* IO.socket() returns a socket for the specified URL and port with the
* default options. Notice that the method caches the result, so you can
* always get a same Socket instance for an url from any Activity or
* Fragment.
* */
mSocket = IO.socket("http://192.16x.xxx.yyy:8000");
} catch (URISyntaxException e) {
e.getMessage();
}
/*
* We then can make the socket listen an event on onCreate lifecycle callback.
* */
mSocket.on("welcome", onNewMessage);
/*
* And we explicitly call "connect()" to establish the connection here.
* In this app, we use onCreate lifecycle callback for that, but it
* actually depends on your application.
* */
mSocket.connect();
}
private Emitter.Listener onNewMessage = new Emitter.Listener() {
#Override
public void call(final Object... args) {
MainActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
String message = (String) args[0];
mTextView.setText("Received from Server: " + message);
}
});
}
};
/*
* Since an Android Activity has its own lifecycle, we should carefully manage the
* state of the socket also to avoid problems like memory leaks. In this app, we’ll
* close the socket connection and remove all listeners on onDestroy callback of
* Activity.
* */
#Override
protected void onDestroy() {
// socket gets disconnected
mSocket.disconnect();
// off() removes the listener of the "welcome" event
mSocket.off("welcome", onNewMessage);
super.onDestroy();
}
}
The client code is also very simple: It connects to the server and displays the message it gets from the server.
I got this ex. from the official Socket.IO website at https://socket.io/blog/native-socket-io-and-android/.
When I start the server with node server.js on the terminal of my laptop and use an Android emulator, then everything works fine.
But when I connect my real Android device to my laptop using a USB then the connection does not take place.
Why Android app (running within the real device) does not connect to the server ?
This worked for me: I created a socket with the IP 0.0.0.0, You should Change your IP at your node.js to this value.
Than i opened cmd and entered ipconfig to see what my ip adress is, this is your local IP adress. In the Code i am connecting to this IP Adress.
For example if you see IP 192.168.178.50 in your ipconfig you Change your Android Code to
mSocket = IO.socket("http://192.168.178.50:8000");
And your Node.js Code should look like
const ip = '0.0.0.0';
And dont Forget to Restart your Server when you changed the node.js code
I have started developing live streaming using kurento media server. I have Installed kurento media server in Ubuntu 14.04TLS. It gets successfully Installed and also started successfully.
I have used STUN server, I have uncommented these two lines
stunServerAddress=<stun_ip_address>
stunServerPort=<stun_port>
And used IP, PORT as follows: 173.194.66.127:19302
.After doing all these thing I started kurento media server and it gets started.
Now I create Android native application by implementing RoomListener Interface.
Here is the Code to connect with Kurento Media Server.
public class MainActivity extends AppCompatActivity implements RoomListener {
private LooperExecutor executor;
private static KurentoRoomAPI kurentoRoomAPI;
private String TAG = "MainActivity";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
executor = new LooperExecutor();
executor.requestStart();
String wsRoomUri = "wss://173.194.66.127:19302/room";
kurentoRoomAPI = new KurentoRoomAPI(executor, wsRoomUri, this);
kurentoRoomAPI.connectWebSocket();
}
#Override
public void onRoomResponse(RoomResponse response) {
Log.d(TAG, "Response");
}
#Override
public void onRoomError(RoomError error) {
Log.d(TAG, "Error: " + error.toString());
}
#Override
public void onRoomNotification(RoomNotification notification) {
Log.d(TAG, "Notification Received");
}
#Override
public void onRoomConnected() {
Log.d(TAG, "Connected");
}
#Override
public void onRoomDisconnected() {
Log.d(TAG, "Room Disconnected");
}
}
But when I run the application, it shows the following error:
Process: com.base.videostreamingkurento, PID: 1880
java.lang.AssertionError: java.net.SocketTimeoutException: failed to connect to /173.194.66.127 (port 19302) after 90000ms
at libcore.io.IoBridge.connect(IoBridge.java:117)
at java.nio.SocketChannelImpl.connect(SocketChannelImpl.java:199)
at org.java_websocket.client.WebSocketClient.interruptableRun(WebSocketClient.java:210)
at org.java_websocket.client.WebSocketClient.run(WebSocketClient.java:188)
at java.lang.Thread.run(Thread.java:818)
Caused by: java.net.SocketTimeoutException: failed to connect to /173.194.66.127 (port 19302) after 90000ms
at libcore.io.IoBridge.connectErrno(IoBridge.java:189)
at libcore.io.IoBridge.connect(IoBridge.java:127)
at libcore.io.IoBridge.connect(IoBridge.java:115)
It seems that you have a little confusion with your deployment and IPs. You are trying to connect, from your client, to the STUN server. Instead, try setting the IP and PORT where your app server is located in this line
String wsRoomUri = "wss://APP_SERVER_IP:8443/room";
If you can draw that down, you'll see more clearly where everything goes and what should connect to what.
I connect to the node server with socketio.SocketIO running as a service.And, When Service restarts,opens socket.io without socket.io closure.That's a problem.
A device making multiple socketIO connection on the server side.So the server is swelling..
! I am using gottox/socketio-java-client on android.
Check Socket is connected or not using socket.isConnected().
This will return true if socket is connected
Its just an idea so i don't know the limitations. pls let me know.
You can ping the server to check if the connection is alive.
In android
socket.emit("ping","ping");
socket.on("pong",pingHandler); //EmitterListener
private Emitter.Listener pingHandler=new Emitter.Listener(){
#Override
public void call(final Object... args) {
Log.d("SocketStatus","Connection is active");
});
}
and make the server return response for the ping
socket.on("ping",function(data){
socket.emit("pong","pong"); //from your server ex.Node.js
});
You can check the socket.connected property:
var socket = io.connect();
console.log('Connected status before onConnect', socket.socket.connected);
socket.on('connect', function() {
console.log('Connected status onConnect', socket.socket.connected);
});
It's updated dynamically, if the connection is lost it'll be set to false until the client picks up the connection again. So easy to check for with setInterval or something like that.
Another solution would be to catch disconnect events and track the status yourself.
The following is an expansion/modification of Rafique Mohammed answer above. The correct way is to try to reconnect on client side.
Internet drops (server cannot communicate disconnection to client). Server crashes (server may/may not be able to tell client. Server Restart (server can tell but that just extra work). After reconnection you will also like to rejoin the room for seamless communication
public void connectAfterDisconnectSocket(String senderActivity) {
new Timer().scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
boolean isConnected = false;
isConnected = mSocket != null && mSocket.connected();
if (!isConnected) {
SocketIOClient socketIOClient = new SocketIOClient();
socketIOClient.connectToSocketIO();
if (senderActivity.equals("A")) {
A.joinChatRoom(room);
}
if (senderActivity.equals("B")) {
B.joinChatRoom(room);
}
}
}
}, 0, 1000); //put here time 1000 milliseconds=1 second
}
Dont get angry on me please. I have two questions, I think on very similar theme, so I decided to merge them into one. I have my app on android that is using sensors to do some calculations. I am storing there sesults in my database. What i want to do is to send my data from my phone to my desktop app also with a database (on button click).
To be more precise, here is an example: My light sensor reads current light intensity. Lets say it is 1000lux. Now, when I click my button "Send" in my android app, it will send this value to my desktop apps database. That desktop app will read that value and will show it to user.
Is it possible via WIFI? or better via web, so i will not be limited with distance?
How can android manage this kind of communication?
And my second question is, if controlling media player on my PC is similar to what i said.
EDIT:
I did some research and found one Socket tutorial. I tried it exactly like it is there. So i have this in my android app:
public class Client extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_client);
Client myCli = new Client();
try {
myCli.run();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_client, menu);
return true;
}
public void run() throws Exception {
Socket mySkt = new Socket("192.168.1.6", 9999);
PrintStream myPS = new PrintStream(mySkt.getOutputStream());
myPS.println("Hello server");
BufferedReader myBR = new BufferedReader
(new InputStreamReader(mySkt.getInputStream()));
}
}
and this in netBeans:
//Author: WarLordTech
//Website: http://www.youtube.com/user/WarLordTech
import java.io.*;
import java.net.*;
public class Server {
public static void main(String[] args) throws Exception{
Server myServ = new Server();
myServ.run();
}
public void run() throws Exception{
ServerSocket mySS = new ServerSocket(9999);
Socket SS_accept = mySS.accept();
BufferedReader SS_BF= new BufferedReader(new InputStreamReader
(SS_accept.getInputStream()));
String temp = SS_BF.readLine();
System.out.println(temp);
if (temp!=null) {
PrintStream SSPS = new PrintStream(SS_accept.getOutputStream());
SSPS.println("Got something");
}
}
}
It still isnt workiong. Do I have to set up my network somehow?
You could do it using TCP Sockets. Many languages have implementations for Socket programming so you would "need" to program your desktop app in Java (of course that is always possible!).
Socket Tutorial in Java
This would work over the net and local wifi. You could use other methods for local wifi such as a UDP connection. You'd need to setup a TCP server and make sure you had access etc.
There may be other ways to do this but it's not such a trivial task to do!
I'm developing an android app using socket. But Socket soc=new Socket(ip,port) always give me a SocketTimeoutException. I use socket in a java project, it's Ok. But not in an android project.
public static void main(String[] args) {
try{
Socket soc=new Socket("192.168.177.103",8888);
}catch(Exception e){
e.printStackTrace();
}
}
This is all right, but not in an android project. Why?
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_mmmm);
new Thread(){
public void run(){
try{
Socket soc=new Socket("192.168.177.103",8888);
}catch(Exception e){
e.printStackTrace();
}
}
}.start();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_mmmm, menu);
return true;
}
Could someone tell me why? Thank you very much.
The Exception details when use socket in android:
java.net.SocketTimeoutException: Connection timed out
at org.apache.harmony.luni.platform.OSNetworkSystem.connect(Native Method)
at dalvik.system.BlockGuard$WrappedNetworkSystem.connect(BlockGuard.java:361)
at org.apache.harmony.luni.net.PlainSocketImpl.connect(PlainSocketImpl.java:204)
at org.apache.harmony.luni.net.PlainSocketImpl.connect(PlainSocketImpl.java:183)
at java.net.Socket.startupSocket(Socket.java:732)
at java.net.Socket.tryAllAddresses(Socket.java:152)
at java.net.Socket.<init>(Socket.java:211)
at java.net.Socket.<init>(Socket.java:178)
at com.example.mmmmm.MMMMActivity$1.run(MMMMActivity.java:26)
Your server 192.168.177.103 is not responding in timely manner, or at all. It may also be that the port 8888 is closed by its firewall. So this is actually not the Android device problem.
If the returned content is HTTP based, use some desktop PC connected to the same LAN to check if the server responds to the ordinary browser request. Also, try
adb shell ping 192.168.177.103
This would allow to verify if the server is accessible. However ping may be disabled on your server, especially if it is a Windows machine.
If the server is accessible from desktop connected through the wired network and is still not accessible from Android, it may also be great to check how the firewall of your wireless router is configured.