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.
Related
I'm re-writing a tcp server program in .net core.
I have difficulties implementing my design.
The server has three basic functions/services:
service 1. accept and manage client connections
service 2. handle each kind of client messages and send acknowledge message
service 3. keep track of inactive clients(clients who haven't sent any message for a time) and close those connections.
I'd like to have each of these functions on a dedicate IHostedService.
But I've no idea how should these services communicate with each other.
These services are registered by AddHostedService, and seem can't be injected.
And I'm not sure if it's a correct way to expose public methods on a Hosted Service for others to call.
The most relevant SO question I've found is this one.
In my situation, it means that I should register one mediator service for each of the three services. It doesn't seem to be a clean way because these mediators are just for communication, without semantic meanings...
I'd like to know if the mediator is the only approach,
or is my design totally incorrect?
That really depends on strategy. Each hosted service could take in a configuration as part of its dependencies for communication. However, TCP port binding will need to be unique.
In a prior life, I wrote a UDP service that broadcast and which TCP services were available for communication and mediated the services in chat room sort of setup. UDP is more of a wide net whereas TCP is specific addressing.
If you were using only TCP, without configuration those services would need to know who is the mediator and what address to reach it at.
I wrote messenger in c# with sockets, but i have little problem with ports. To clear comunication I have to open port on router which i use in my messenger. How to resolve this problem? Is method to automatic open default closed ports?
Thanks.
There are a couple things you can do.
The first is to change the programming of your application so that it uses the regular http port (80) for communication. This would allow your app to make outbound calls pretty much anywhere.
Alternatively you could use a high port number from 49152 through 65535. ( See Assigning TCP/IP Ports for In-House Application Use ).
However, depending on where you are deploying your application it is highly likely that all of those ports are blocked via firewalls; and neither will solve your problem
Most messenger type applications can't go direct due to firewall issues. For example, even if you use port 80, its likely the client machines have that port blocked for incoming TCP requests.
Instead they typically connect to a known public server. When one client wishes to connect to a different one, the server will route the message between the two clients. A very simplified look at this is: Client A sends a communication request to the server for Client B. Client B polls the server for messages, sees one and shows it on the desktop.
There are ways to keep the TCP connection alive between the clients and server in order to speed up communications; but that's the basics.
There are even ways for clients to directly talk to each other, when they determine that certain ports are open for communication or that proxy servers aren't going to interfere with the traffic. However, that's a little more advanced than a simple "answer" here can provide.
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.
The remote client is a desktop application running a windows.forms application. How do I have the server send the client a message, knowing the client's IP address?
Check out these tutorials:
Simple Threaded TCP Server
High Performance TCP/IP Server using C#.NET
Building a TCP/IP server using C#
and these books
TCP/IP Sockets in C#: Practical Guide for Programmers (The Practical Guides)
C# Network Programming
Although sockets is an option, you may want to consider using a higher level abstraction such as the one provided by WCF.
WCF's Duplex Services allows you to implement communication going both ways (client -> server) and (server -> client) with some flexibility on choosing transport and protocol.
A common way to do this is using sockets.
Basically you open up a communication channel to the remote client using TCP/IP and can send messages back and forth. Both sides must know about the other and must agree on a message format.
When using sockets, you communicate on a port. Several ports are reserved for (or at least typically used by) certain protocols. For example, HTTP uses port 80 by default. You will want to select a port not already in common use. Also be sure that any firewalls between both ends allow communication on that port.
It could largely depend on the existing protocol that is being used between the client and the server. If the server is HTTP, then the client could poll to see if there are messages. If the client is already using TCP/IP, then ideally the server can send a message to the client any time it needs to.
Also, keep in mind that opening a communication channel may essentially be one way (i.e. from the client to the server), depending on firewall configuration (such as NAT).
In general terms you do that by replying to a request of the client. If you don't have client requests, the distinction between servers and client becomes rather blurred.
What do I use for two way communication over the internet without the necessity to open ports on the client side?
Users won't agree to open ports and do port forwarding on the client side although everything is possible on the server side.
But,I need to accomplish two way communication..
How do I go about achieving this?
It doesn't matter whether its WCF or remoting or webservices...
I just need a quick and fast way to just get the concept to work out and distribute the application.
ofcourse,it's going to be through the internet.
Please help..
Thanks
Edit : Please note that i need to connect multiple clients and maintain a session for each client.
WCF supports duplex HTTP bindings.
As long as the initiating client can access the service, a callback contract can be defined to call the client. It simply keeps the HTTP connection once the client has initiated it.
It depends what you want to do. Duplex WCF can work, but through NAT and Proxies it becomes somewhat "iffy" because it depends on the client opening a WCF endpoint and maintaining the connection.
I wrote a beginners guide to WCF callbacks a while ago - it's simple enough to do, but you'll need to test it a lot, from various client setups.
Connect via TCP (raw sockets, or higher implementation) to a your central server.
Your server should have an application that listens to a specific, well known, TCP port.
Each client connects to your server, using the specific port, and "logs in".
Write an application protocol above the TCP (authentication, session management, etc.), and there you have it, since a TCP connection, once established, works for both directions.