I am developing a TCP server, which shall communicate with the client, if specified tasks are finished. So I open on the server a socket and the client connects on it.
That connection can be used for data tranfers back to the client, too. That is quite okay.
But what about connection aborts and anything like that?
My thought was to connect each time to the server, when the client have to communicate with it. But how can I send data back to the client?
Shall I open a socket on the client side, too?
EDIT:
I have considered WCF, too. I think it could be a very good way to implements server client hierarchy.
What do you think?
It depends on the rest of your requirements. If we're talking a message that is in no rush that might be sent once a day, the right solution might be for the client to connect to the server periodically and check if there are any messages. If we're talking something that's more common and more in a rush, the right solution might be for the client to keep a connection open to the server at all times. In some cases, the right solution might be for the server to make a 'backwards' connection to the client, if possible -- perhaps with an option to fall back to a persistent connection from the client to the server if the 'backwards' connection isn't possible.
See this article on Push technology, particularly the section on long polling.
From a runtime POV having the server connect to the client needs a network environment supporting this (firewall/IDS etc.).
IF you can't be sure that this is always the case then this option is ruled out IMO.
As for the client keeping the connection open:
I think this is a good option... you need to make sure that the client implementation detects any connection problems and automatically reconnects...
Whatever solution you implement you might need to implement a queue of events per client... depending on your requeirements these queues might even need to be persistent...
WCF can work in all the ways I described and offers several things (like serialization, optional session management, transport security etc.) which help build a robust and well-maintainable system... although a pure TCP/IP-based solution might be better performance-wise...
Related
I'm writing a windows based client(c++) and server(c#) application which will communicate to each other via tcp packets. Here the client is sending data and server needs to acknowledge the same.
Now for this purpose I have made one single 'socket()' and 'connect()' call during the client lifetime on its startup. Some error checking and retries has been kept inside 'send()' and 'recv()' calling methods. Do note that one client will send one set (multiple packets) of data and quit at a time.
Now my questions are:
If the server is running continuously(e.g. windows service) on some PC, do I really need to consider about connection
breakdown(network failure) and creating a new socket and connect
accordingly from client?
If that be so, shall I need to consider resending the data from starting or from the point where client has failed to communicate last
time?
I want to know the general methods what people are using around the world for dealing this kind of situations for network applications.
do I really need to consider about connection breakdown and creating a new socket and connect accordingly from client?
Depends on how precious your data is. If you want to make sure it ended up at the server, and an error occurred while sending, then you can consider it "not sent".
If that be so, shall I need to consider resending the data from starting or from the point where client has failed to communicate last time?
That depends entirely on how your application logic and application protocol work. From your description we can't know how you send your data and how a server would recognize data it has already seen.
do I really need to consider about connection breakdown(network
failure) and creating a new socket and connect accordingly from
client?
You do certainly not need to create a new socket after connection shutdown; you can use the existing socket to connect anew.
I am in the need of creating a C# program that will run on couple of our local Windows client machines. These 'client' programs will have to take commands from a 'admin' program run on another machine.
The commands could be to reboot the client computers, return some local information about IP address etc back to the 'admin' program.
But how to accomplish this? I know a little about WCF but is that the right way to go?
If I go with WCF I will then have to make the client programs run a service method, like every second, to check for new commands. With sockets I establish a 'direct' connection and the client just waits for a command to receive - isn't that correct understood?
Which way would be the right way for me to go?
We are talking about ~10 clients and I want a maximum delay (send command - receive info back) of 1 second.
Any hints would also be appreciated.
Best regards
Duplex WCF server. Basically, the clients all connect into the server (so only 1 server), and the server uses its duplex channel to call back to the clients whenever it needs to. No polling, scales well, etc. The most headache you'll need to deal with is to set a long timeout in case that you don't send anything for a while so that the channels time out.
WCF will end up being much simpler in the end.
A couple of links:
http://msdn.microsoft.com/en-us/library/ms731064.aspx
and
http://www.codeproject.com/Articles/491844/A-Beginners-Guide-to-Duplex-WCF
I hope those help.
You can make WCF clients act as servers and with command & control program connect to them that is no problem. Go for WCF if you don't want to mess with ugly stuff that sockets can bring. WCF can be configured nicely in app.config, and you can make it really self hosted command line application even so no need for IIS server. Configuration will be then resuable and easier to maintain.
You could use .NET Remoting which can provide a "push" backchannel from the server to the client (using "callbacks"). It does not need a 2nd TCP connection in the other direction so you don't need to mess with client's firewalls and routers.
Remoting is considered kind of obsolete but it has its places.
In any case I would not use a WCF polling technique. That leads to bad latency and a DDOS situation for the server.
If you can make the clients open a port then hosting a WCF service there is probably the best idea.
I would recommend a socket implementation as in the long run it probably gives you greater flexibility. You could create this from scratch yourself using the socket namespace. As an alternative you could use an off the shelf network library solution. Checkout lidgren and NetworkComms.Net.
Disclaimer: I'm a developer for NetworkComms.Net.
With the small number of machines and modest performance requirements you mentioned, I think WCF would end up being easier than sockets.
You might look into Duplex WCF. I've never used it, and WCF has given me headaches in the past any time I've needed anything unusual, but it's for the sort of problem you're talking about.
If all the machines are on one network, here's one creative alternative loosely inspired by message queues: you could use a database table as a place where messages appear and get read by clients at their leisure. The clients could just query it and say: get me all messages where MessageID > LastReceivedMessageID.
The downsides of that last approach is that (a) you're still doing polling although your database server should be able to handle it and (b) if you might ever need this outside of your network, you would need a VPN or a new solution.
you could use MSMQ... couldn't be easier to implement
http://msdn.microsoft.com/en-us/library/windows/desktop/ms711472(v=vs.85).aspx
I use MSMQ for a number of similar applications. Works perfectly.
Making a client/server style app using WCF, but I can't find any documentation that explains if the NetTcpBinding provides a persistent connection?
I would like my client to connect and remain connected to the server for weeks at a time. (Yes I know I need to handle disconnects etc..)
Does the NetTcpBinding allow for a long connection such as this? If so is there anything I need to specify or is this default behaviour?
As long as you keep the service host and client proxy alive and opened, the underlying connection in WCF should remain opened as well. Even below that, it appears that the binding uses connections from the TCP connection pool, as found on the NetTcpBinding MSDN page:
The NetTcpBinding uses TCP connection pooling based on the service’s host DNS name and the port number the service is listening on.
I'm not an expert on how TCP connection pooling works, you may want to try a sister site such as ServerFault for more details on this.
If you want control over all this, then the only property I can see that can be tweaked for the out-of-the-box NetTcpBinding is MaxConnections. However, if you're really willing to dive deep you can also build your own Custom Binding with a TcpTransportBindingElement, that gives you even more fine-grained control on the TcpConnectionPoolSettings.
In any case, if I were to venture a guess I'd think building the service host and client proxy will take far more time (relatively) than any time spent getting a connection from the pool, so keeping those two opened may be enough for your requirements.
The reason I asked in a comment why you want the connection to remain open is because that can hardly be a requirement in itself. Speed and response times are a real requirement though, so the best advice is probably to make those requirements explicit (quantify / qualify your need for speed) and run some tests to determine what's best/needed for your situation.
When I was experimenting with C# and WCF one of the things I kept reading about was how unscalable it is to have clients with a constant current connection to the server. And although WCF allows that it seems that the recommended best practise is to use 'per call' as opposed to 'per session' for instance management if you want to have any kind of decent scalablity. (Please correct me if Im wrong)
However from what I understand IRC uses constant client connections to the server and IRC servers (well networks of servers) are servicing hundreds of thousands of clients at any given time. So in that case is there nothing actually 'bad' about keeping constant client connections to the server?
As long as you don't follow the one-thread-per-connection architecture, a server can support quite a large number of concurrent TCP connections.
IRC doesn't require much per connection state, beyond the TCP send and receive windows.
If you need real-time duplex communication (IRC is a chat protocol), then keeping a TCP connection alive is a relevant option. However, TCP connection brings network overhead and operating systems have practical limits on the number of concurrent open TCP connections. WCF is commonly used in SOAP/HTTP/RPC contexts where duplex communication is not required, but certainly it offers suitable bindings and channels for that as well. To answer your question, there is nothing bad in keeping the connection open if you have real-time, duplex requirements for your communication.
Yes, such architecture is feasible, but... The "ping? pong!" thing was invented for a reason - to let both parties know that the other party is still there. You cannot actually tell if a client is idle, because it does not have much to say or because it is actually disconnected and you are waiting for a TCP timeout.
UPD: "hundreds of thousands of clients" is possible on IRCnet only because of server networks. For a single machine, the C10K problem is still an issue.
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.