ZeroMQ, how to connect to external tcp socket? - distributed

Can you please tell me how you can use to send messages ZeroMQ between two programs located on different servers using some common socket?
With all local sockets program works, but I do not understand how they spread to different places. Because climbs error:
Traceback (most recent call last):
File "/Users/*****/Projects/*****/workers/internal_links_parser.py", line 20, in <module>
socket.bind("tcp://***.***.***.***:5000")
File "socket.pyx", line 447, in zmq.core.socket.Socket.bind (zmq/core/socket.c:4312)
zmq.core.error.ZMQError: Can't assign requested address
Explain, please, and if not difficult to give an example. Thx!

From the zmq socket manual on Socket.bind;
This causes the socket to listen on a network port. Sockets on the other side of this connection will use Socket.connect(addr) to connect to this socket.
In other words, this will tell 0mq to listen to a local port for incoming connections; you should use something like socket.bind("tcp://0.0.0.0:5000") to listen to all of the machine's IP addresses on port 5000.
The other side of the connection should use Socket.connect with an URL something like socket.connect("tcp://remoteip:5000") to connect to the other side listening.
It would seem from the error message that you're trying to bind to the remote address instead of binding to the local and connecting to the remote.

Don't forget to check the firewall. It should be inactive.
Also, you can check to know if the server is accessible or not with telnet:
telnet serverIPaddress serverPortNo

Related

Bind in TCP/UDP Sockets

Bind function is used to assign a name (a sockaddr struct) to a socket descriptor. Why is it required for TCP server but not TCP client ? And why it is required for bot UDP Client and server?
I have also written correctly working code without using bind() in UDP Client .
I do not understand why bind() is not used universally i.e. in all cases above.
Binding is only a required, if there is no other way for the computer to know which program to send the packets to. For connection less programs this is only the receiving end.
Please have a look at socket connect() vs bind() this post.
There a much better job of explaining is done than I'm able to do. If you've got any questions after. Feel free to ask:)
Client on calling connect implicitly bind to a ephemeral, available port provided by the kernel. It need not specifically bind because it is the initiator of the connection. Server explicitly need to bind because it need to tell external world (the clients) how they can reach the server. Server listens on that port.Client knowing that published port initiates connection to it.
Now servers can send packets to client because on connection establishment the peer details (IP and Port) becomes known and are part of connection identifier.
And the above applied to both TCP and UDP. (UDP will not have connect)

How do apps like LogMeIn and TeamViewer work?

There's already a question How exactly does a remote program like team viewer work which gives a basic description, but I'm interested in how the comms works once the client has registered with the server. If the client is behind a NAT then it won't have its own IP address so how can the server (or another client) send a message to it? Or does the client just keep polling the server to see if its got any requests?
Are there any open source equivalents of LogMeIn or TeamViewer?
The simplest and most reliable way (although not always the most efficient) is to have each client make an outgoing TCP connection to a well-known server somewhere and keep that connection open. As long as the TCP connection is open, data can pass over that TCP connection in either direction at any time. It appears that both LogMeIn and TeamViewer use this method, at least as a fall-back. The main drawbacks for this technique are that all data has to pass through a TeamViewer/LogMeIn company server (which can become a bottleneck), and that TCP doesn't handle dropped packets very well -- it will stall and wait for the dropped packets to be resent, rather than giving up on them and sending newer data instead.
The other technique that they can sometimes use (in order to get better performance) is UDP hole-punching. That technique relies on the fact that many firewalls will accept incoming UDP packets from remote hosts that the firewalled-host has recently sent an outgoing UDP packet to. Given that, the TeamViewer/LogMeIn company's server can tell both clients to send an outgoing packet to the IP address of the other client's firewall, and after that (hopefully) each firewall will accept UDP packets from the other client's Internet-facing IP address. This doesn't always work, though, since different firewalls work in different ways and may not include the aforementioned UDP-allowing logic.

Retrieving local IP before a connection is made

I am trying to determine which local IP would be used on a socket for a TCP connection towards a given host on Linux, using C.
Let me make an example. I could connect my socket and use getsockname() on the file descriptor to get the local ip (and local TCP port); but can I do this without opening the connection?
I could read the routing table and make a decision based on that - but the networking subsystem must have that algorithm already, for when the connection is actually open. In short, I'd like to know if there is an API to access the routing algorithms without having to parse the rules myself or opening an actual connection. The solution - if any - will probably be Linux only but that's OK.
EDIT: someone on IRC suggested I create a UDP socket and use connect() on it. No network is used at that point but I should be able to use getsockname() on it
The only solution I know to this is what traceroute does. Send a packet with a TTL of 1 and see which interface the ICMP return comes in on. As I recall there are lots of incompatibilities between different hosts, so there's probably several different types of messages you might need to send/receive to get the data you need.

When to use bind() when programming with sockets?

I am writing a simple sender and receiver program to transit using UDP so it's connectionless, but I am having a problem figuring out whether my receiver program needs to call bind() or the server and/or both. My receiver program(client) will sit in an infinite loop waiting to receive data from the sender(server) and then it will print out the data. I'm not quite sure what bind() does exactly besides associating an address/port with a specific socket. Why is it that I need to call bind()?
You need to call bind(2) so that the OS knows which application to route network packets to. When you call bind with a specific port for a given protocol (e.g. TCP or UDP), you're asking it "whenever you see a network packet on port XXXXX, please give it to me".
Say, for example, that two copies of your program were running, and they both wanted to listen for UDP packets on the same port. If they both call bind on the same port, then one will succeed and one will fail, since the OS can arbitrate who is bound to each port. Then, any packet received on that port will be given to whichever instance of the program succeeded at binding to that port.
when you want to make a socket a fixed address or/and port, you use bind.
See you when developing a Network Application you need to specify "Address and Port" to Bind because if you want to set it for Localhost your application is not able to communicate with the all over the network its only for your system which its communicating.. If you set it with your Network address it's not able to communicate as localhost Its only communicate with the network and If you set it to 0 then It can be use as both for localhost and Network.

C Get IP for listening server

I am writing a client/server program using C sockets. I am specifying that the server can listen on any network interface by using INADDR_ANY in sockaddr_in.sin_addr.s_addr. This is equivalent to an IP of 0.0.0.0. Is it possible for me to get the actual IP that the server is listening on? (e.g. 192.168.1.100)
When you bind a listening socket to INADDR_ANY, the socket listens on all available local IPs. There is no way to determine from the socket which IP(s) it is listening on. If you need that information, then you have to enumerate the local IPs separately (in which case you could just bind() each IP to its own socket individually if you need to retreive pre-accept binding details). However, once accept() has returned an established client connection, you can use getsockname() on the accepted socket to know which specific IP accepted the connection.
I have finally been able to find a solution that works.
Edit: link is dead so see: Internet Archive link.
Hopefully it can be helpful to others as it has been to me.

Resources