Async Sockets example which shows passing an object? - c#

I need to create a server process which can push high frequency data (1000 updates per second) to around 50 client. I'm thinking the best way you do this is using async sockets with the SocketAsyncEventArgs type.
The client -> server connections will be long running at least several days to indefinite. I plan to have a server process listening and the clients connect and the server starts pushing the data to the clients.
Can someone point me to or show me an example of how to do this? I can't find any example showing a server process pushing an object to a client.
EDIT: This is over a gigibit LAN. Using windows server with 16 cores and 24gb ram
thanks

First, some more requirements from your side is required. You have server with lots of muscle, but it will fail miserably if you don't do what has to be done.
can the client live without some of the data? I mean, does the stream of the data need to reach other side in proper order, without any drops?
how big is 'the data'? few bytes or?
fact: scheduling interval on windows is 10 msec.
fact: no matter WHEN you send, clients will receive it depending on lots of stuff - network config, number of routers in-between, client processor load, and so on. so you need some kind of timestamping here
Depending on all this, you could design a priority queue with one thread servicing it and sending out UDP datagrams for each client. Also, since (4) is in effect, you can 'clump' some of your data together and have 10 updates per second of 100 data.
If you want to achieve something else, then LAN will be required here with lots of quality network equipment.

If you want to use .NET Sockets to create this server-client project, then this is a good outline of what's needed:
Since the server will be transferring data to several clients simultaneously, you'll need to use the asynchronous Socket.Beginxxx methods or the SocketAsyncEventArgs class.
You'll have clients connect to your server. The server will accept those connections and then add the newly connected client to an internal clients list.
You'll have a thread running within the server, that periodically sends notifications to all sockets in the clients list. If any exceptions/errors occurs while sending data to a socket, then that client is removed from the list.
You'll have to make sure that access to the clients list is synchronized since the server is a multithreaded application.
You don't need to worry about buffering your send data since the TCP stack takes care of that. If you do not want to buffer your data at all (i.e. have the socket send data immediately), then set Socket.NoDelay to true.
It doesn't seem like you need any data from your clients, but if you do, you'd have to make sure your server has a Socket.BeginReceive loop if using Socket.BeginXXX pattern or Socket.ReceiveAsync method if using SocketAsyncEventArgs.
Once you have the connection and transmission of data between server and client going, you then need to worry about serialization and deserialization of objects between client and server.
Serialization which occurs on the server is easy, since you can use the BinaryFormatter or other encoders to encode your object and dump the data onto the socket.
Deserialization on the other hand, which occurs on the client, can be pretty complex because an object can span multiple packets and you can have multiple objects in one packet. You essentially need a way to identify the beginning and end of an object within the stream, so that you can pluck out the object data and deserialize it.
One way to do this is to embed your data in a well known protocol, like HTTP, and send it using that format. Unfortunately, this also means you'd have to write a HTTP parser at the client. Not an easy task.
Another way is to leverage an existing encoding scheme like Google's protocol buffers. This approach would require learning how to use the protocol buffers stack.
You can also embed the data in an XML structure and then have a stream-to-XML decoder on your client side. This is probably the easiest approach but the least efficient.
As you can see, this is not an easy project, but you can get started with the Socket.BeginSend examples here and here, and the SocketAsyncEventArgs example here
Other Tips:
You can improve the reliability of your communication by having the client maintain two connections to the server for redundancy purposes. The reason being that TCP connections take a while to establish, so if one fails, you can still receive data from the other one while the client attempts to reconnect the failed connection.
You can look into using TCPClient class for the client implementation, since it's mostly reading a stream from a network connection.

What about rendezvous or 29 west? It would save reinventing the wheel. Dunno about amqp or zeromq they might work fine too....

Related

Keeping track of a file transfer percentage

I've begun learning TCP Networking with C#. I've followed the various tutorials and looked at the example code out there and have a working TCP server and client via async connections and writes/reads. I've got file transfers working as well.
Now I'd like to be able to track the progress of the transfer (0% -> 100%) on both the server and the client. When initiating the transfer from the server to client I send the expected file size, so the client knows how many bytes to expect, so I imagine I can easily do: curCount / totalCount on the client. But I'm a bit confused about how to do this for the server.
How accurate can the server tell the transfer situation for the client? Should I guess based on the server's own status (either via the networkStream.BeginWrite() callback, or via the chunk loading from disk and networking writing)? Or should I have the client relay back to the server the client's completion?
I'd like to know this for when to close the connection, as well as be able to visually display progress. Should the server trust the client to close the connection (barring network errors/timeouts/etc)? Or can the server close the connection as soon as it's written to the stream?
There are two distinct percentages of completion here: the client's and the server's. If you consider the server to be done when it has sent the last byte, the server's percentage will always be at least as high as the client's. If you consider the server to be done when the client has processed the last byte the server's percentage will lag the one of the client. No matter what you do you will have differing values on both ends.
The values will differ by the amount of data currently queued in the various buffers between the server app and the client app. This buffer space is usually quite small. AFAIK the maximum TCP window size is by default 200ms of data transfer.
Probably, you don't need to worry about this issue at all because the progress values of both parties will be tightly tied to each other.
Should I guess based on the server's own status (either via the networkStream.BeginWrite() callback, or via the chunk loading from disk and networking writing)?
This is an adequate solution.
Or should I have the client relay back to the server the client's completion?
This would be the 2nd case I described in my 1st paragraph. Also acceptable, although not necessarily a better result and more overhead. I cannot imagine a situation right now in which I'd do it this way.
Should the server trust the client to close the connection (barring network errors/timeouts/etc)?
When one party of a TCP exchange is done sending it should shutdown the socket for sending (using Socket.Shutdown(Send)). This will cause the other party to read zero bytes and know that the transfer is done.
Before closing a socket, it should be shut down. If the Shutdown call completes without error it is guaranteed that the remote party has received all data and that the local party has received all data as well.
Or can the server close the connection as soon as it's written to the stream?
First, shut down, then close. Closing alone does not imply successful transfer.

C#: Question about socket programming (sync or async)

I'm writing an instant messaging server in C# for learning purposes.
My question is whether I should use synchronous or asynchronous sockets to handle the IM clients. The goal is to handle as many clients as possible.
I'm not quite sure but as far as I know with async sockets the packets don't arrive in order which means when you send 2 chat messages and there is a delay/lag it's possible that the second one arrive before the first one. Is this right and if so, is there a way to solve this issue?
About sync sockets: Is synchronous sockets a good solution for many clients? Do I have to check every socket/connection in a loop if there are new packets? If so, isn't this quite slow?
Last question: Assume I want to implement a way to send files (e.g. images) through the protocol (which is a non-standard binary protocol btw), can I still send messages while uploading?
The goal is to handle as many clients as possible.
Async then. It scales a lot better.
I'm not quite sure but as far as I know with async sockets the packets don't arrive in order which means when you send 2 chat messages and there is a delay/lag it's possible that the second one arrive before the first one.
TCP guarantees that everything arrives in order.
Assume I want to implement a way to send files (e.g. images) through the protocol (which is a non-standard binary protocol btw), can I still send messages while uploading
I recommend that you use a separate connection for file transfers. Use the first connection to do a handshake (determine which port to use and specify file name etc). Then use Socket.SendFile on the new socket to transfer the file.
Everything #jgauffin said (i.e. TCP handles packet-order, async better for n(clients) > 1000).
Assume I want to implement a way to send files (e.g. images) through the protocol (which is a non-standard binary protocol btw), can I still send messages while uploading?
Your custom protocol has to be built to support this. If you write a 8MB packet to the Socket, you won't be able to write anything else using that socket until the 8MB are sent. Instead, use upload-chunks of smaller size so that other packets have the chance to go over the pipe as well.
[UPLOAD id=123 START length=8012389]
[UPLOAD id=123 PART chunk=1 length=2048 data=...]
[UPLOAD id=123 PART chunk=2 length=2048 data=...]
[MESSAGE to="foo#example.com" text="Hi"]
[UPLOAD id=123 PART chunk=3 length=2048 data=...]
// ...
[UPLOAD id=123 COMPLETE checksum=0xdeadbeef]
The difference between an async approach and a sync approach is more about the difference between non-blocking and blocking io. With both approaches, the data is delivered in the same order that it has been transmitted. However, you don't block while you wait for an async call to complete, so you can start transmitting to all of your clients, before any of the individual communications has finished writing to the socket (which is why typically it would be the approach followed by servers).
If you go down the sync route, you block until each transmission / receive operation has completed, which means you may require need to run multiple threads to handle the clients.
As far as uploading an image at the same time as sending messages, you may want to handle that down a different pipe connection between the client/server so that it doesn't cause a blockage.

Multiple client IPC in .Net

I have a server process bound to a port that receives network packets at essentially random intervals. When a packet is received it is parsed and an object representing this packet's data is created. I would like to be able to 'push' this data object to any number, 0..n, client processes running on the same machine. The clients will always be on the localhost.
A client process is only interested in data objects created and pushed by the server since it was launched. This is also a one-way only flow of information. Client's do not need to communicate with the server they just need to receive any new data objects from the server.
The server and client processes are both written in C# using the .Net framework.
Given this setup, what method of IPC would you use to get this to work? My current plan is to serialize the data object and write it to a named pipe that clients read from. Is this the way to go? Also worth noting is that speed isn't a critical factor.
I solved this using WCF callbacks. Clients 'subscribe' to the server, the server then iterates over the subscribed callbacks and calls them with the data to be pushed. When a client process is ended it issues an unsubscribe.
There are loads of examples of this on the net that are fairly easy to follow. For anyone interested these links might help.
http://msdn.microsoft.com/en-us/magazine/cc163537.aspx
http://dotnetaddict.dotnetdevelopersjournal.com/wcf_alarmclock.htm
http://idunno.org/archive/2008/05/29/wcf-callbacks-a-beginners-guide.aspx

TCP or UDP help with a server/client in c#?

Can anyone help, i trying to figure what i need to do, i have been given the tasks of writing a server and a client in TCP (UDP). basically multiple clients will connect to the server.. and the server sends MESSSAGES to the client.
I have no problem in creating the server and client but with tcp i am unsure whcih way to go. DOes the .net 3.5 support everything or do i need to go on the hunt for some component?
I am looking for soome good examples with c# for TCP or UDP. THis is where i am not 100% sure .. as far as i know there is UDP and TCP ... 1 is connected and 1 is not.. So which way do i go and can c# support both?? Advantages /Disadvantages?
Say if the server has to support multiple clients that i only need to open 1 port or do i need to open 2?
Also if a client crashes i need for it not to effect the SERVER hence the server can either ignore it and close connection if one is open or timeout a connection... If in fact a connection is needed again going back to tcp udp
Any ideas where i shoudl beging and choosing which protocol and amount of ports i am going to need to assign?
thanks
UDP cons:
packet size restriction means you can only send small messages (less than about 1.5k bytes).
Lack of stream makes it hard to secure UDP: hard to do an authentication scheme that works on lossy exchange, and just as hard to protect the integrity and confidentiality of individual messages (no key state to rely on).
No delivery guarantee means your target must be prepared to deal with message loss. Now is easy to argue that if the target can handle a total loss of messages (which is possible) then why bother to send them in the first place?
UDP Pros:
No need to store a system endpoint on the server for each client (ie. no socket). This is one major reason why MMO games connected to hundred of thousands of clients use UDP.
Speed: The fact that each message is routed individually means that you cannot hit a stream congestion like TCP can.
Broadcast: UDP can broadcast to all listeners on a network segment.
You shouldn't even consider UDP if you're considering TCP too. If you're considering TCP means you are thinking in terms of a stream (exactly once in order messages) and using UDP will put the burden of fragmentation, retry and acknowledgment, duplicate detection and ordering in your app. You'll be in no time reinventing TCP in your application and it took all engineers in the word 20 years to get that right (or at least as right as it is in IPv4).
If you're unfamiliar with these topics I recommend you go with the flow and use WCF, at least it gives you the advantage of switching in and out with relative ease various transports and protocols. Will be much harder to change your code base from TCP to UDP and vice versa if you made the wrong choice using raw .Net socket components.
It sounds to me like you're not clear on the distinction between TCP and UDP.
TCP is connection oriented. i.e. 2 peers will have a dedicated connection. Packet delivery and ordering is guaranteed. Typically a server will present a port, and multiple clients can connect to that port (think of a HTTP server and browsers).
UDP is connectionless. It doesn't guarantee packet delivery, nor ordering. You can implement broadcast and multicast mechanisms very easily. If you need some sort of reliability, you will have to implement this on top of UDP. Sometimes you may not care, and simply issue requests and retry on no response (SNMP does this). Because it's connectionless, you don't really worry about peers being up/down. You just have to retry if required.
So your choice of protocol is dictated by the above. e.g. does your client require a dedicated connection to the server ? Are you transmitting the same data to multiple clients ? Can you tolerate packet loss (e.g. real time price updates etc.). Perhaps it's feasible to use both TCP and UDP for different requirements within your app (e.g. TCP for registering orders, UDP for transmitting price updates/events?)
I'd consider your requirements, and familiarise yourself with the limitations and features of TCP and UDP. That should make things a little clearer.
Is there a requirement to do this at such a low level? Why not use WCF? It fully supports messaging over TCP/IP, using binary data transfer, but it's at a much higher level of abstraction than raw sockets.
Everything you need is in .Net 3.5 (and probably below). Check out the documentation and examples with the UdpClient class at MSDN for insight into how to write your client/server. A quick google found some sample code for a server and client at www.java2s.com among many other networking examples in C#. Don't be put off by the domain name.

How would you notifiy clients about changed data on the server using .Net 2.0?

Imagine a WinForms client app that displays fairly complex calculated data fetched from a server app with .Net Remoting over a HTTPChannel.
Since the client app might be running for a whole workday, I need a method to notify the client that new data is available so the user is able to start a reload of the data when he needs to.
Currently I am using remoted .Net events, serializing the event to the client and then rethrowing the event on the side of the client.
I am not very happy with this setup and plan to reimplement it.
Important for me is:
.Net 2.0 based technology
easy of use
low complexity
robust enough to survive a server or client restart still functional
When limited to .Net 2.0, how would you implement such a feature? What technologies / libraries would you use?
I am looking for inspiration on how to attack the problem.
Edit:
The client and server exist in the same organisation, typically a LAN, perhaps a WAN/VPN situation.
This mechanism should only make the client aware that there is new data available. I'd like to keep remoting for getting the actual data to the client since that is working pretty well. MSMQ comes with windows, doesn't it? So it should be ok to use it, but I'm open to any alternative.
I've implemented a similar notification mechanism using MSMQ. The client machine opens a local, public queue, and then advises the server of it's queue name. When changes occur, the server pushes notifications into all the client queues that it's be made aware of. This way the client will know that data is ready, even if it wasn't running when the notification was sent.
The only downside is that it requires MSMQ on the clients, so this may not work if you don't have that kind of control over your client's machines.
For an extra level of redundancy (for example, if a client machine is completely down, and therefore the client queue is unavailable) you could queue notifications on the server prior to dissemination to clients. Notifications in the server queues are only removed when the client is successfully contacted (or perhaps after 3 failed attempts, etc.)
Also in that regard, if the server fails to deliver messages to a client a measured number of times, over a measured period of time, then support entities are notified, error alerts go out, and the client queue is removed from the list of destinations. When I say "measured" I mean a frequency/duration that makes sense to the setting. In my case, it was 5 retries with 5 minute intervals between attempts.
It might also make sense to have the client "renew" it's notification subscription at intervals. If a renewal doesn't occur, then eventually the client queue is removed from the destination list by a "groomer" process in the service.
It sounds as though you need to implement a message-queue based solution. Easy to implement, can survive reboots, and the technology is mature both on the server (MSMQ, MGQSeries) and on the client (System.Messaging)
If you can't find anything built-in and assuming you know the address of all the clients, you could send them a UDP message when data changes. Using UdpClient, this is very easy. The datagram doesn't even need to contain any data if the client app can assume that any UDP data on a certain port means it needs to get new data from the server.
If necessary, you can even make this a broadcast packet (if you don't know who the clients are and they are on the same subnet as the server), so long as the server isn't too "chatty".
Whatever solution you decide on, I would urge you to avoid having the clients poll. This will create a lot of unecessary network traffic and still won't perform all that well.
I would usually use a UI timer on the client to periodically hit the server to see if there was new or updated data. (Assuming you have a mechanism to identify that you have new data like time stamps for new rows, or file time stamps, or a table with last-calculated dates, etc)
That way the server doesn't have to know about the clients. The clients can check at their leisure, etc.

Categories

Resources