I'm not sure how best to approach my problem. I have a service with runs on a remote machine with receives and process UDP packets. I want the service to be able to re-send these packets to anyone that happens to want them (could be no-one, will typically be one machine, but may be more)
I figured UDP Multicasting would be ideal - the service can send to the multicast group and it doesn't matter how many receivers have registered, or even if there are none.
However, I want to be able to access this over the internet and from what I gather this is nigh-on impossible with UDP Multicasting. Is there another method I might use to achieve this?
If relevant, both my client and service are written in C#.
In general this is not possible since multicast packets aren't routed.
There are some techniques to work around this (DVMRP, MOSPF and others) but they all require that you can configure all the routers between your server and the clients (or create a tunnel). There are backbone networks (Abilene, Mbone) with multicast support, but those are of most interest for universities and such. The normal consumer's internet does not have multicast.
Unfortunately you need point-to-point communication. But you are in good company, internet, radio and TV all do point-to-point, transmitting the same data numerous times. Quite a waste of bandwidth.
The preferred method is to use overlay multicast, i.e. use TCP links between peers and implement multicast semantics above that.
Many IPv4 routers do not support multicast or have it disabled, IPv6 is mandated to support multicast and broadcast semantics have been removed.
Related
The project is to build a messaging mechanism between a Python and C# program via ZeroMQ .
I want messages to be able to travel in/out from both ends at any time, which is NOT a basic request-reply model a.k.a. REQ/REP.
One way I can think of is to build a PUB/SUB model on two ports, i.e. two one way channels.
Is there any method to get a real duplex channel?
There are several ways to do this with ZeroMQ. I suggest using a DEALER/ROUTER socket pair:
Choose one program to be the "server", the other the "client".
The server will bind a ROUTER socket on a port.
The client will connect a DEALER socket to the server's ROUTER port.
(Note: this implies that the client must know the server's IP and port in advance.)
At this point the client can send messages to the server, but the server has no way to send to the client.
The client sends a "HELLO" message to the server.
The server will receive a message that includes the client's address and the HELLO message. Now the server can send messages to the client using the client's address.
DEALER/ROUTER is considered an "advanced" socket pair in ZeroMQ. My description here is very high level. You'll really need to read the docs to get the most out of ZeroMQ.
Oh yes, Sir!
Use the PAIR-PAIR or even the XREQ-XREP ought make it.
The best next step is to carefully read the respective Scalable Formal Communication Pattern archetypes' access-points' API documentation, so as to cross-check, that all pieces of pre-wired behavioural logic meet your Project needs and voilá, harness them in your messaging setup and tune-up the settings so as to meet you performance and latency needs.
That is this simple ( thanks to all the genuine knowhow hidden in these builtins ).
Using for years this very sort of inter-platforms integration among Python + C/MQL4 and other computing nodes, so well worth one's time to learn the powers and strengths of ZeroMQ.
I have the same dilemma as the one who posted this topic, Real-time communication with WCF
except that my problem is not about games programming. I would like to know what's the best method to use to be able to have a real time communication in between two windows applications (server-client). I am using visual c++/c# to date and i would like to be able to display all the Feeds that are being received by my server to the client in real time.
I have started trying to use .NET remoting but in my continuous research, it appears that it will use SOAP-http, and might affect the speed of the communication. My server and client will communicate using the internet and .NET remoting does not permit the use of TCP Channel when communicating in between a firewall or the internet.
Your inputs will be greatly appreciated.
I guess it depends on your escenario, if you want "real-time" and you are willing to lose some packages in the process you are better with UDP, take a video conferencing tool for example, by the time you recover your slow packages you will have to move and display the next frame in the video or audio; that is a good example for the use of UDP. This is the reason why UDP is much faster than TCP.
If however, you are not willing to lose a single bit of your message, then TCP was made for you because if you lost a package the protocol will request it again to have your complete message as complete as possible.
Additionally it depends on the way the communication is being sustained, is the information flowing from one to many?, from many to many?, one to tone?
Take NetNamedPipeBinding for instance, this will be much faster process, but is only deployed in a single machine but accross processes. Whereas NetMsmqBinding will help you to build queues and it will be amazingly reliable and scalable for scenarios where your load will be a massive number of connections.
In the end, it all boils down to your concrete escenario and your business goals.
Hope it helps
If you are willing to do your own message parsing, you can use standard TCP sockets with the TcpClient and TcpListener classes. If your data is already a serializable object, you could serialize it into a text stream and just send it over the socket, deserializing it on the client side.
To get it to work over the internet, the server needs to have the port forwarded on your router, the client would just attach to the server's public IP. You would obviously need to add an exception in your firewall for this port as well.
The biggest problem with WCF and large data is setting up the streaming, by default WCF sends everything at once, which isn't practical for large files.
I've built a server-application for a game that I want general people to use. Now, since I've worked with client/server solutions before, I know how tedious it is to host connections on some computers.
So, I heard about these rumors that I would like to get confirmed.
Using UDP for "hosting" a connection is good, because it is rarely blocked by router-firewalls compared to TCP.
Using UPNP for communicating with a router is good, because it allows you to add port forwarding for the game, making your server reachable no matter if you're using TCP or UDP.
I don't care about the software-firewall people may use. What I care about is the router firewall functionality.
Any help would be appreciated.
Thanks!
For your two rumors,
I don't know, I have not worked with firewalls enough, but I would not call that one true. Most routers block everything (TCP and UDP) unless you explicitly ask it to forward it for inbound connections via hand setup or UPNP. If you don't tell the router what computer wants info coming in to port 12345 how will it know what to do when a user sends a unsolicited packet to it (the definition of being a server).
Yes, learning how to do UPNP will make it a lot easier for your users to host games, however you should still provide instructions for people who do not have UPNP turned on or their router does not support it.
The other thing you may want to look in to is learning how to add your program to the windows firewall client allowed list as that is what most of your users will have. See this SO question for more details.
I am writing a custom p2p program that runs on port 4900. In some cases when the person is behind a router, this port is not accessible from the internet.
Is there an automatic way of enabling the access to the port from the internet. I am not really sure of how other p2p applications work.
Can anyone please throw some light on this?
P2P connectivity in a nutshell. Assume we're talking about UDP here. The steps below can also be applied to TCP with some adjustments.
Enumerate all your local IP addresses (usually only 1). Create a UDP socket on a given port number** for each adapter with an IP address.
For each socket created in step 1, contact a STUN or TURN server with that same socket to discover your external IP address and to discover what the internal port number maps to outside of the NAT (it's not always the same port value). That is, your local address 192.168.1.2:4900 might be 128.11.12.13:8888 to the outside world. And some NATs don't always use the same port mapping when using the same local port to other IP addresses. TURN will also provide you a "relay address". You can also use UPNP to get a port mapped address directly from your router, if it supports that protocol.
Through a rendezvous service (SIP, XMPP, instant message, web service, email, cups with strings), publish your address candidate list to a service or send a notification to the other client that says, "hey, I want to connect with you". This message includes all the "address candidates" (ip and port pairs) collected in steps 1 and 2.
The remote client, upon receiving the invite to connect, performs step 1 and 2 above as well. Then sends back his candidate list through the same channel that he received the inviter's candidate list on.
Hole punching step. Both clients, start sending test messages over UDP to the other side's address candidates and listening for the same messages on their end. Whenever a messages is received, reply back to the address from which it came. Eventually, the clients will discover that they have a pair of addresses that they can reliably send datagrams too. Typically, one endpoint makes the final decision on which address pair (sockets) to communicate with and the protocol facilitates this endpoint telling the other endpoint this decision.
**- usually best to not to rely on a well known port for P2P clients. Because two clients behind the same NAT or firewall would not likely be able to use your software at the same time.
Here is a quick summary of some technologies to explore.
STUN - Is a simple server and protocol for clients behind a NAT/route to discover what their external IP and port mappings are.
TURN is an expansion to STUN, but supports relaying for P2P connectivity scenarios where firewalls and NATs prevent direct connections.
ICE is a set of steps by which STUN and TURN are used for setting up a P2P connection. ICE is a formal protocol for steps 1-5 above. Two excellent set of slides on ICE are here and here.
WebRTC is a variant of the ICE standard as well as a reference library for make P2P sessions with STUN and TURN.
UPNP + Internet Gateway Device Protocol - Some routers support this for hosts to automatically obtain port mappings.
libnice is an open source C library for Linux (and might work on windows) that implements ICE.
libjingle is another ICE implementation (in C++) from Google. For Windows and Linux.
PJNATH is a library within the PJSIP suite of coding libraries. It is a good implementation of an ICE stack (C code) and has been ported to a lot of platforms. (Windows, Linux, Mac, iOS, Symbian, and soon Android).
And finally, I have a blatant plug for you to use my STUN server code base.
There are solutions in some cases, see UPnP: https://en.wikipedia.org/wiki/Universal_Plug_and_Play#NAT_traversal
My home router allows this, basically, the NAT can be configured automatically by the proper request from the computer.
I would not count on this to provide a big improvement in your availability, because not that many routers both support that and have it enabled.
EDIT: #David suggested this SO question for a .NET library for UPnP: Is there a UPnP Library for .NET (C# or VB.NET)?
I would use WebRTC technology as an open source framework for such application.
Official Website
In fact it is an open source project which supports all necessary for peer-to-peer technologies out of the box:
ICE and STUN (NAT traversal)
DTLS and SRTP (security)
AVPF for quality of streaming.
This may be a little more complicated than what you're looking for, but TCP Hole Punching is a technique that should work. http://en.wikipedia.org/wiki/TCP_hole_punching
Alternatively, UPnP works great for routers / firewalls that support it.
You have another option that is NAT Port Mapping Protocol (NAT-PMP)
NAT-PMP is widely used by VoIP applications like Skype or BitTorrent P2P clients.
For the simple beginnig I would recommend to see hole punching technique. Great video here. But be sure it will not always work relating the network topology. This solves the ICE technique which discovers how connection could be established.
My Winforms client/server application relies on UDP multicast to update all clients in real time. The server fires events into a known UDP sink, and each client receives them, both using instances of the System.Net.Sockets.UdpClient class.
This works great -- when it works. Each client has a remoting object on which it makes its synchronous calls, via TCP, and UDP handles the asynchronous stuff, so the client remains stateless. But many of our clients have UDP disabled in various ways -- some disable multicasting, some disable UDP altogether, some have it disabled on purpose, others by accident. I end up doing a lot more network administration than I would like.
The other choice, it seems to me, is for the server to manage client connections and send the events over TCP, but this requires a stateful server and does not seem very attractive. Are there superior alternatives?
You can try using WCF and the publish/subscribe design pattern. I moved a winforms TCP/UDP app much like you described to WCF using netTCP binding and a UDP broadcast for the clients to find the server, once they find it, they subscribe and you use WCF callback contracts to update the clients. You'll need to have intelligence on both sides if a connection is dropped.
Also in your case if the server is always a set address with WCF callbacks you wouldn't need to use UDP to find the server, so you could eliminate UDP and just rely on the netTCPBinding to push messages to clients and vice versa.