I can run my Qt DBus test by connecting to the session bus:
QDBusConnection connection = QDBusConnection::sessionBus();
connection.registerService(...)
....
TestserviceInterface testserviceInterface( .... , connection, &a);
But can I connect to this DBus from a different computer. I know I can do something like this:
connection = QDBusConnection::connectToPeer("tcp:host=127.0.0.1,port=45000", Testservice::ServiceName);
But how would I obtain the port? Whatever I have tried, there seems to be no connection. Or am I at the wrong path here and need to us Peer 2 Peer DBus instead of the session bus?
I am almost sure the service name is correct, as I can see it qdbusviewer. When I use dbus-monitor the output does not mean a lot to me, I cannot see any port, etc.
Any idea how I would be able to connect from another computer?
PS: I am aware that there is something like gabriel for tunnelling via SSH (http://gabriel.sourceforge.net/howto.html). This is not what I am up to, I am looking for a "direct connection".
Session bus daemon usually listens unix socket /var/run/dbus/system_bus_socket ( check your /usr/local/etc/dbus-1/session.conf config ) which means that you can't access it remotely via tcp. Start some kind of port forwarding on computer where bus daemon is running (using socat for example) or configure it to listen tcp.
You can use SSH to create a tunnel for DBus.
ssh -nNT -L ./dbus_on_local:/var/run/dbus/system_bus_socket user#remote
Explanation
This will create a local "file" (unix domain socket) dbus_on_local that you can connect to.
Related
I'm new in work with interprocess communication. I need you help and clear explanation. I have 2 applications. One of them is a service and one is a client. I've used QT/C++ to write them. When they are working on the one local PC - all is good. But I need to separate them.
So, I have a service on the PC with IP 192.30.82.101.
I connect it to bus using next code:
QDBusConnection connection = QDBusConnection::sessionBus();
connection.registerObject("/my/service/MyService", mySvc);
connection.registerService("my.service.MyService");
Also I have a client on the another PC with IP 192.30.82.40.
I connect my client using the next code:
QDBusServiceWatcher serviceWatcher = new QDBusServiceWatcher();
serviceWatcher->setConnection(QDBusConnection::sessionBus());
serviceWatcher->addWatchedService("my.service.MyService");
.....
myServiceProxy = new local::MyService("my.service.MyService",
"/my/service/MyService", QDBusConnection::sessionBus(), this);
I need to connect my client on the PC with IP 192.30.82.40 to the service on the PC 192.30.82.101. I don't know how to do this. I've found a few topics on the forum but I still don't understand what to do.
So, what I have found:
On the PC where is my service I have to add additional lines to /etc/dbus-1/session.conf:
<listen>tcp:host=<host>,port=<port></listen>
<listen>unix:tmpdir=/tmp</listen>
<auth>ANONYMOUS</auth>
<allow_anonymous/>
Here I have a question: Which IP address I have to use here (server or client)? Which port is used for DBUS (is it default port or how I can check it)? I have tried to set an IP address of my client PC, my service PC and different ports, and port 0, but I've got an error: Failed to bind socket "172.30.82.40:0": Cannot assign requested address.
On the client side I have to set DBUS_SESSION_BUS_ADDRESS with the same address: export DBUS_SESSION_BUS_ADDRESS=tcp:host=<host>,port=<port>.
I've tried to do this with different ports, with 0 port, because this means - use any free port. But I cannot start bus daemon with any port+IP configuration.
Also I've tried to connect client QDBusServiceWatcher to bus using the next code:
serviceWatcher->setConnection(QDBusConnection::connectToBus("tcp:host=<host>,port=<port>", "session"));
It was not successful.
I have no idea how to connect them to each other.
Can anybody, please, explain me how it should be, how does it work?
I want to clearly understanding how does it work?
I will be very grateful for any help. I hope for your kindness.
UPDATE
I have found how to connect my client to DBus bus via TCP:
On the PC where is my service I have to add additional lines to /etc/dbus-1/session.conf:
<listen>tcp:host=localhost,bind=*,port=6667,family=ipv4</listen>
<listen>unix:tmpdir=/tmp</listen>
<auth>ANONYMOUS</auth>
<allow_anonymous/>
Here we should add PORT. We can find it in dbus config file.
On the client side I have to set DBUS_SESSION_BUS_ADDRESS with corresponding address (IP of PC where is service):
export DBUS_SESSION_BUS_ADDRESS=tcp:host=192.50.88.10,port=6667,family=ipv4.
Thats all. We can check it just started dbus-monitor.
But now I have another issue: how to connect my client to my service?
I need to do something more to connect to my service.
I guess that this is something like:
QDBusConnection::connectToBus("tcp:host=<host>,port=<port>","connectionName");
I've tried to connect with any random name, but this is not correct.
So, my question is - where I can get correct connection name?
Correct answer to my question is:
On the PC where is one application add additional lines to
/etc/dbus-1/session.conf:
<listen>tcp:host=localhost,bind=*,port=6667,family=ipv4</listen>
<listen>unix:tmpdir=/tmp</listen>
<auth>ANONYMOUS</auth>
<allow_anonymous/>
Correct port you can find in dbus config file.
On the client side It's needed to set DBUS_SESSION_BUS_ADDRESS with
corresponding address (IP of PC where is service):
export DBUS_SESSION_BUS_ADDRESS=tcp:host=192.50.88.10,port=6667,family=ipv4.
To connect to session where is alive your remote app use the next
connection string:
DBusConnection::connectToBus("tcp:host=192.50.88.10,port=6667", "qt_default_session_bus"));
How to know session name? I've added log in my service:
qDebug() << "Connection name: " << connection.name();
Then started app, copy printed name and set it in my client.
Now it works!
Is there any server-client like inter-process-communication method which allows:
the server to reliably get the process-ID of a connected client
any client-application to connect to the server
works in C/C++
Optionally: Works also on Linux
Since your server runs with root rights, you can work with task_for_pid() and a two way connection. First, the client will send its pid to the server via some special bootstrap port on the server, the server will then resolve the pid via task_for_pid to a task port and then use mach_port_insert_right to insert a send right to a new port into the client. The new port is then exclusively to the client and you know what security level the client has.
In my Qt application I am using a peer to peer DBus connection. Server runs on computer A, client on B, connected via DBus TCP/IP connection. Works fine.
I wonder if I can somehow find out whether the server is running and what its IP address is? So far I need to provide the correct address/port in the client.
Both, server and client run in a local network. Of course, I can use a trial and error approach and ping all machines in my network. Is there something better, something like a broadcast asking for the server, and the server responding appropriately? Is Qt providing something for this?
I have a C++ Program listening for incoming socket connections on port 2222.
I have an Adobe AIR/Flex application that attempts to connect to it, when I click a button.
When I Connect To My Socket Over My Intranet, My C++ program hears and accepts the incoming socket connection and Everything Works Fine:
var Sock:Socket=new Socket("192.168.1.100",2222);
But When I Try To Connect Using My Real IP, I Get Error #2031:
var Sock:Socket=new Socket("76.18.24.118",2222);
Both programs are running on my laptop computer. I am behind a router, but have configured that router with port forwarding so that port 2222 maps to my laptop.
What Am I Missing? I am very new to this, so perhaps I'm missing something obvious to you smarties.
What does the error code mean (see your docs for socket)
Are you sure the receiving server process is alive?
The traditional starting point is Beej's guide
Port forwarding does not mean that you can use an external IP address, your laptop is still on the private 192.168 network. What it means is that when someone tries to connect on 78.18.24.118:2222 the router converts the IP address to 192.168.1.100:2222. This effectively allows you to run a server inside your network but allows an outside client to connect to you.
Look up DNAT for more information.
Is there any method in c++/vc++/mfc so that I can verify whether remote machine is on network or not. I don't want to use ping command. I tried to use WSAConnect method but it takes lot of time in searching if remote machine is not on network. In that case application windoe freezes for long time. I need alternate way to verify remote machine netwotk connectivity. Plz help
You can check to see if a host name exists and if DNS can resolve an IP address for it, but this won't tell you if it's online. In order to determine if it's online, you must exchange data with the host. For this to happen the host must be listening on a port, and must send some sort of response.
Generally, the lowest common denominator for hosts is the ICMP packet - aka ping. You can write your own service in C++ to send these UDP packets, and detect a reply.
Some hosts and some routers disable ICMP to appear 'invisible'. If you know that your host accepts connections on a TCP port, you can attempt to create a tcp socket. For example, from a shell you can test using nc
nc -z google.com 80
Connection to google.com 80 port [tcp/http] succeeded!
If you do raw socket programming, you can attempt to connect to a host via, and then call select() with a short timeout.
If you don't want your app to block, use a thread.
If the only issue is that calling WSAConnect locks up your UI, you can try calling it in nonblocking mode.
Call WSAEventSelect to set the socket to nonblocking mode prior to calling WSAConnect. You then call WSAAsyncSelect or WSAEventSelect to check the status of the connection.
MSDN's page on WSAConnect has some remarks about nonblocking mode here.
You can use tracert command. Example:
tracert -w 1000 192.168.0.77
You can check if the machine is connected to a network, but without trying to transmit data to a site residing on the internet I don't think there is a way to check if that network is actually online. For example your end user might as well be connected to a DSL router which is not online at the moment.
You can use arping for it.
Also some smart switch can talk about attached host.