I create a simple windows service that has two threads: main and worker. In main thread I put code that helping us to control worker threads states: Running, Pause, Continue and Stop. In worker thread I put code that begin accepting of the incomming connections and restarting acceptance when its really needed.
Worker thread working with async sockets that hiddes from us that we are creating one more thread (I'll name it ASYNCSOCKETS in text below). That helps to deal with performance issues, due to non-blocking code executing everywhere. :) I recommend to look into code, because I don't want to put many technical details here.
At the moment of accepting of incomming connection I create special CommunicationContext class that store information about incomming and outgoing sockets, buffers and communication state. You can use this context class for collecting and storing statistics information on sockets, control different states of communication and etc. - its depends on your needs.
Service now allowing to create up to 5 tunnels (this is hardcoded, but you can simply change that).
Issues
1) One from issues that I catch that with .NET sockets I have to deal a lot with exceptions handling. In Windows API sockets layers it was much simplier, you just have to check the state code after each API call. But at the end of the development I found a good point of using exceptions handling (look into NoDataSocketException class usage).
2) CommunicationContext destroying I give to do GC, but if you are developing high performance proxy server, then better to free resources by own hands then waiting for GC (buffers that used by sockets eating memory very fast!).
3) I try to use Disconnect logic for sockets, but it does not work as I expect that is why I Close sockets instead of Shutdowing and Diconnecting.
4) Proxy works only in one direction, I mean server/deestination host can not initialize connection, but you can easily repeat that logic based on code in archive.
Debugging technics
1) please make a look on files
_switches.cs and
_tracer.cs - this is helper classes that enhance .NET System.Diagnostics functionality and give us easy interface for tracing activitied of our code; in
APP.CONFIG file you can find how to configure tracing in more advanced way.
2) debugging of the windows service is a little tricky part. Please make a look into
service_debug.reg file. It force window OS to start debugger when we starting windows service. So to debug service you have to do several simple steps:
- run *.reg file for updating windows registry;
- compile service source code;
- open service control panel and select service in it. Press Start;
- in window that will ask you about debugging select existing instance on Visual Studio with opened source code.
- place break points in source code where you need them;
3) It's not always so easy to debug windows service that is why I implement additional functionality that should help in service debugging: command line options. Service understand several commands: -install, -uninstall, -help, -debug
DEBUG option force service to start in console mode! that is much easier to debug!!
References
At the moment when I mostly complete my code writting I found a good article in code project that demostrate mostly the same "business issue", but programming and architcture done in differen way. So I recommend to look into that code too if you are interesting in Proxy/Sockets programming:
HERE