Faking IO Streams - c#

As part of my student group's hobby project, I'm creating a simulation of a wired network of microcontrollers in order to test the algorithms we've written. Each controller is wired up to several data ports, which each have an input and output stream. I'm modeling this relationship by giving each port a BinaryReader and BinaryWriter, each backed by its own MemoryStream. However, I ran into a snag when trying to 'connect' ports between different controllers. Simulating the latency is outside the scope of this iteration of the simulation, so I just needed to link them directly somehow.
So my question is this: how can I fake an IO stream like this using two different BinaryReader/BinaryWriter or MemoryStream sets, such that when I write to one the other can immediately read it?

I ended up using UDP sockets connected to each other via the loopback address, which simulated the asynchronous nature of the network well without dealing with latency issues.
I'm not allowed to publish the actual code, but the implementation was fairly straightforward. Each data port has its own UdpClient from the System.Net.Sockets namespace and a randomly assigned UDP port. An update loop iterates over each port and calls the udpClient.Send() and udpClient.Receive() functions as appropriate, using a simple byte[] buffer to handle incomplete messages. I think an overview of high-level networking in .Net is outside the scope of this question, but there's some nice resources available on MSDN just a Google search away.

Related

Good UDP relay server design

I'm creating a UDP server that needs to receive UDP packets from various clients, and then forward them to other clients. I'm using C# so each UDP socket is a UdpClient for me. I think I want 2 UdpClient objects, one for receiving and one for sending. The receiving socket will be bound to a known port, and the sender will not be bound at all.
The server will get each packet, lookup the username in the packet data, and then based on a routing list the server maintains, it will forward the packet to 1 or more other clients.
I start the listening UdpClient with:
UdpClient udpListener = new UdpClient(new IPEndPoint(ListenerIP, UdpListenerPort));
udpListener.BeginReceive(new AsyncCallback(OnUDPRead), udpListener);
My callback looks like:
void OnUDPRead(IAsyncResult ar)
{
UdpClient udpListener = (UdpClient)ar.AsyncState;
try
{
IPEndPoint remoteEndPoint = null;
byte[] packet = udpListener.EndReceive(ar, ref remoteEndPoint);
// Get connection based on data in packet
// Get connections routing table (from memory)
// ***Send to each client in routing table***
}
catch (Exception ex)
{
}
udpListener.BeginReceive(new AsyncCallback(OnUDPRead), udpListener);
}
The server will need to process 100s of packets per second (this is for VOIP). The main part I'm not sure about, is what to do at the "Send to each client" part above. Should I use UdpClient.Send or UdpClient.BeginSend? Since this is for a real-time protocol, it wouldn't make sense to have several sends pending/buffered for any given client.
Since I only have one BeginReceive() posted at any given time, I assume my OnUDPRead function will never be called while already executing. Unless UdpClient works differently than TcpClient in this area? Since I don't give it a single buffer (I don't give it any buffer), I suppose it could fire OnUDPRead several times with only one BeginReceive posted?
I don't see any reason why you can't use one socket, the straightforward way. Async I/O doesn't appear to me to offer any startling benefit in this situation. Just use non-blocking mode. Receive a packet, send it. If send() causes EAGAIN or EWOULDBLOCK or whatever the C# manifestation of that is, just drop it.
In your plan, the sending socket will be bound automatically the first time you call send(). Clients will reply to that port. So it needs to be a port you are reading on. And you already have one of those.
It very much depends on scale - i.e. how many concurrent RTP streams you want to relay. I have developed exactly this solution as part of a media gateway for our SIP switch. Despite initial reservations, I have it working very efficiently using C# (1000 concurrent streams on a single server, 50K datagrams per second using 20ms PTime).
Through trial-and-error, I determined the following:
1) Using Socket.ReceiveFromAsync is much better than using synchronous approaches, since you don't need individual threads for each stream. As packets are received, they are scheduled through the threadpool.
2) Creating/disposing the SocketAsyncEventArgs structures takes time - better to allocate a pool of structures at startup and 'borrow' them from the pool.
3) Similarly for any other objects required during processing (e.g. a RTPPacket class). Allocating these dynamically at such a high rate results in GC issues pretty quickly with any sort of real load. If you avoid all dynamic allocation, and instead use pools of objects you manage yourself, this issue goes away.
4) If you need to do any clocking to co-ordinate input and output streams, transcoding, mixing or file playback, don't try to use the standard .NET timers. I wrapped the Win32 Multimedia timers from winmm.dll - these were much more precise.
I ended up with an architecture where components could expose IRTPSource and IRTPSink interfaces, which could then be hooked-up to create the graph required. I created RTP input/output components, mixer, player, recorder, (simple) transcoder, playout buffer etc. - and then wired them up using these two interfaces. The RTP packets are then clocked through the graph using the MM timers.
C# proved to be a good choice for what would typically be approached using C or C++.
Mike
What EJP said.
Most all the literature on scaling socket servers with async IO is written with TCP scenarios in mind. I did a lot of research last year on how to scale a UDP socket server, and found that IOCP/epoll wasn't as appropriate for UDP as it is for TCP. See this answer here.
So it's actually quite simple to scale a UDP socket server just using multiple threads than trying to do any sort of asynchronous I/O thing. And often times, one single thread pumping out recvfrom/sendto calls is good enough.
I would suggest that the server have one synchronous socket per client. Then have several threads do a Socket.Select call on a different subset of client sockets. I suppose you could have a single socket for all clients, but then you'll get some out-of-ordering problems if you try to process audio packets on that socket from multiple threads.
Also consider using the lower level socket class intead of UdpClient.
But if you really want to scale out - you may want to do the core work in C/C++. With C#, more layers of abstraction on top of winsock means more buffer copies and higher latency. There are techniques by which you can use winsock to forward packets from one socket to another without incurring a buffer copy.
a good design would be not to re-invent the wheel :)
There are already lots of RTP media proxy solutions: Kamailio, FreeSWITCH, Asterisk, and some other open-source projects. I have great experience with FreeSWITCH, and would highly recommend it as a media proxy for SIP calls.
If your signalling protocol is not SIP, there are some solutions for other protocols as well.

C#: SSL with SocketAsyncEventArgs?

I'm developing a socket server using C# .NET. I'm using the async model provided by the SocketAsyncEventArgs class, because it must be a high performance server to support many connections in short periods of time. Next, I want to secure the communication between
clients and server, and I think I could use SSL.
Is there any way of using SSL with the SocketAsyncEventArgs model? I know .NET has the SslStream class for SSL securing, but I need to use SocketAsyncEventArgs for high performance.
Is it possible to use SSL in an upper level, without implementing it in the server code?
Thanks in advance.
Not sure if anyone cares anymore since this is so old but I needed to do just that this week and could not find anything on the internet that met my needs. Maybe there is something new in the framework that does this that I was unable find... Regardless, I would post source code but since I wrote it for my company and they tend to frown on that, I'll just outline the approach I took:
Since SslStream takes a stream in the constructor, I implemented my own Stream subtype with an underlying MemoryStream for reads and another for writes. I also pass in the TcpClient to this object as well.
I used the TcpClient to do the handshake for setting up the SSL connection. After authenticating the server or client depending on how I am using it, I then use my two MemoryStreams for the SslStream read/writes.
So for Async writes, I first write my payload to the SslStream which populates my MemoryStream for writing with encrypted data. With the encrypted data from the MemoryStream, I populate the SocketAsyncEventArgs buffer and call the TcpClient SendAsync method. For reads, it's pretty much the opposite.
I can't say it particular excites me to move the data like that but as long as you don't let your MemoryBuffer objects get reallocated constantly, it's not a performance issue. At least this way, I can use just the framework and my own code without relying on third party software.
You can take third-party implementation of SSL/TLS protocol, such as our SecureBlackbox, and use it with any transport, including .NET Sockets in asynchronous mode. SSL server component of SecureBlackbox doesn't have it's own socket, instead it fires events, in whose handlers you write your socket-related code. This way you an plug any transport, even non-socket one.
I think I may have found a project that provides this.
https://sourceforge.net/projects/socketservers/
I'm still playing with it and am bumping into an issue loading the server certificate, however, looking through the source code it looks promising.
One aspect I'm unsure about is that it p/invokes to secur32.dll rather than being a pure c# implementation, so I'm not sure what the memory/performance impact of that is.
The details on the sourceforge project page are sparse as to what the goal of the project is.

How to send information fast like many games do?

I'm thinking like the methods games like Counter Sstrike, WoW etc uses. In CS you often have just like 50 ping, is there any way to send information to an online MySQL database at that speed?
Currently I'm using an online PHP script which my program requests, but this is really slow, because the program first has to send headers and post-information to it, and then retrieve the result as an ordinary webpage.
There really have to be any easier, faster way of doing this? I've heard about TCP/IP, is this what I should use here? Is it possible for it to connect to the database in a faster way than indirectly via the PHP script?
TCP/IP is made up of three protocols:
TCP
UDP
ICMP
ICMP is what you are using when you ping another computer on a network.
Games, like CounterStrike, don't care about what you previously did. So there's no requirement for completeness, to be able to reconstruct what you did (which is why competitors have to tape what they are doing). This is what UDP is used for - there's no guarantee that data is delivered or received. Which is why lag can be such a problem - you're already dead, you just didn't know it.
TCP guarantees that data is sent and received. Slower than UDP.
There are numerous things to be aware of to have a fast connection - less hops, etc.
Client-to-server for latency-critical stuff? Use non-blocking UDP.
For reliable stuff that can be a little slower, if you use TCP make sure you do so in a non-blocking fashion (select(), non-blocking send, etc.).
The big reason to use UDP is if you have time-sensitive data - if the position of a critter gets dropped, you're better off ignoring it and sending the next position packet rather than re-sending the last one.
And I don't think any high-performance game has each and every call resolve to a call to the database. It's more common to (if a database is even used) persist data occasionally, or at important events.
You're not going to implement Counterstrike or anything similar on top of http.
Most games like the ones you cite use UDP for this (one of the TCP/IP suite of protocols.) UDP is chosen over TCP for this application since it's lighter weight allowing for better performance and TCP's reliability features aren't necessary.
Keep in mind though, those games have standalone clients and servers usually written in C or C++. If your application is browser-based and you're trying to do this over HTTP then use a long-lived connection and strip back the headers as much as possible, including cookies. The Tornado framework may be of interest to you there. You may also want to look into HTML5 WebSockets however widespread support is still a fair way off.
If you are targeting a browser-based plugin like Flash, Java, SilverLight then you may be able to use UDP but I don't know enough about those platforms to confirm.
Edit:
Also worth mentioning: once your networking code and protocol is sufficiently optimized there are still things you can do to improve the experience for players with high pings.

Multi-threaded network UDP server library for .net

Is there something like twisted (python) or eventmachine (ruby) in .net land?
Do I even need this abstraction? I am listening to a single IO device that will be sending me events for three or four analog sensors attached to it. What are the risks of simply using a looped UdpClient? I can't miss any events, but will the ip stack handle the queuing of messages for me? Does all of this depend on how much work the thread tries to do once I receive a message?
What I'm looking for in an abstraction is to remove the complication of threading and synchronization from the problem.
I think you are making it too complicated.
Just have 1 UDP socket open, and set an async callback on it. For every incoming packet put it in a queue, and set the callback again. Thats it.
make sure that when queuing and dequeueing you set a lock on the queue.
it's as simple as that and performance will be great.
R
I would recommend ICE it's a communication engine that will abstract threading and communication to you (documentation is kind of exhaustive).
Problem is that with Udp you are automatically assuming the risk of lost packets. I've read the documentation on ICE (as Steve suggested), and it is very exhaustive. It appears that ICE will work for Udp, however, it appears that Tcp is preferred by the developers. I gather from the ICE documentation that it does not provide any intensive mechanisms to ensure reliable Udp communications.
It is actually very easy to set up an asynchronous Udp client or server. Your real work comes in checking for complete packets and buffering. The asynchronous implementations should keep you from managing threads.
It sounds like you are looking for reliable multicast -You could try RMF , it will do the reliability and deliver the messages using asyc callbacks from the incoming message queue. IBM also does WebSphere which has a UDP component. EmCaster is also an option - however development seems to have stopped back in 2008.
If you aren't going to be transmitting these packets (or events) to other machines you might just want to use something simple like memory mapped files or other forms of IPC.

transferring files using TCP

I'm to trying to develop a program to transfer files using TCP (in a local network) with C#, files should be transfer in encrypted way.
My knowledge about c# is average, and about socket programming just know the basics.
Currently have no idea how to begin.It will be great if you have any suggestion about how to begin, if there is any book, website or any other resources.
You could use WCF with netTcpBinding.
This would encrypt the file during transfer and reduce the development effort, since you do not need to program any low level sockets code.
Unless you want to use it as a learning experience for C#/.NET socket programming, there are a lot of free FTP apis that will do it for you without the pain of having to reinvent the wheel. Indy has been going for almost a decade and the others are fairly stable.
TCP sockets are pretty easy to use. While I don't know the API in c#, it will undoubtedly support a send() method, where you can pass in the bytes of your file, and on the other side it will let you register a callback function that will be called when bytes are received. The TCP protocol guarantees that the data passed in-between will not be corrupted or lost. You will need to encrypt and decrypt the data yourself however.
The easiest way to begin is to code up a 2-client chat program where you send the messages using TCP. If you want to understand more about the TCP protocol and the "network stack" (a set of underlying protocols) then you can start on wikipedia and carry on with a decent book on networks - it is actually a very big topic, but you don't really need to know unless you are making a serious app.
By the way, an easy linux hack is to use netcat (type man nc to get help).

Categories