Introduction

This is a piece of code that I have been using for a long time, which is simple to use, doesn't impose any additional work, and gets the job done for client server communications using the TCP protocol. You just include a single file in your project and get all the benefits.

Kudos to Yuen Chiu So for writing the original article found here (dotnettcp.aspx). The original article only handled strings; my article extends that to a level which you can use in your own client server application which must transfer the detailed objects of data. I have also tweaked and tested the code to get the maximum performance and stability out of it (see the performance test section).

Background

This code came about after using named pipe communication for a long time and having the following problems, although arguably named pipes are faster at data transfer:

Named pipes require authentication on connection to a computer, which is very limiting in non-domain computers and requires the user to enter a valid system user and password on the destination computer to even work.

The named pipe implementation I was using was very large, code wise.

So for the above reasons, I set about creating a replacement which would fit the following requirements:

Simple to use in code, with minimal configuration.

Multi-threaded so it can scale to hundreds of simultaneous users.

Does not impose additional code "proxies" and "contracts" and should work with normal serializable objects.

Does not require computer level authentication, which is implicit in using the TCP protocol as it is handled at a lower level than the OS (unlike named pipes).

Flexibility to implement your own authentication on top of it.

Handle large data transfer objects, e.g., 3 MB data packets.

The test application

Run the solution, and you will get a command line application like in the picture above. Press the 'S' key for server mode, 'C' key for client mode, and anything else for automatic mode which will start sending requests to the server. The application is hard coded to send and receive on the 127.0.0.1 IP address which is the local system; you can change this to test on a real network with different computers.

The data.cs file contains the sample POCO data object which is hard coded to a 3 MB size; you can change this to test smaller and larger data packets (see the performance test section).

Using the code

To use the code, first you must create your data packets like the ones below:

As you can see, the best performance is with a CHUNK_SIZE of 32 KB for both small and large data packets. You can go higher, e.g., 64 KB, but you get diminishing returns, and possibly (I don't know for sure), you may have problems with some switches and routers in the network as they might block large packet sizes.

Points of interest

I have put the network server code in a NETSERVER conditional compilation block so you will have to add that to your project definition. There is a Config class in the NetWorkClient.cs file which has some predefined options that I have tweaked to maximum performance; one note worthy option is NUM_OF_THREADS which is how many threads the server creates to handle a request. The default is 10, which should be enough for most applications; I have used it for handling 50+ clients applications in real world circumstances.

What you can do at home or further directions

Below is a list of possibilities you can do at home if you feel adventurous:

Progress Events: events to publish the progress of data for the client application to hook on to and display UI for.

Share

About the Author

Mehdi first started programming when he was 8 on BBC+128k machine in 6512 processor language, after various hardware and software changes he eventually came across .net and c# which he has been using since v1.0.
He is formally educated as a system analyst Industrial engineer, but his programming passion continues.

* Mehdi is the 5th person to get 6 out of 7 Platinums on CodeProject (13th Jan'12)

Comments and Discussions

hi Mehdi Gholam
Is it possible to copy data from a device through any of the network machines
I am trying to read log file from a fingerprint Scanner ,connected in lan using
ip 192.168.1.212 and port 4370.

Thanks Mehdi Gholam for ur reply.
My aim is to copy the attendance log files from the fingerprint reader machine.the machine is connected to one of the lan ports on the same network.I know the ip address of the device and port no,But dont know how to read from the device.My finger print machine vendor is http://www.esslindia.com/Products.aspx?Id=E9999[^]
I am not using the sdk provided by the vendor (to make the application device independent)
Plz share any helpful links and source codes .I cant access the devices memory

Quote:

If both sides use the same code then yes, otherwise you will have to create the protocol of the finger print scanner.

can u tell me more about what u mean by "both sides"(i think what u mean is client and server but in my case how can i code on client side its the fingerprint device).
How can i create protocol for finger print scanner?

thanks Mehdi Gholam for ur reply.
I have checked the sdk and dll's before,its not free version and doesn't support other vendors. I will try some other solution.can u suggest me some matching reference links for my requirement.thanks in advance

You should really use the code in the doc version of RaptorDB (NetworkClient.cs) since it is better and supports compression, json and bjson, until I get round to posting back here.

A programmer walks into a bar and asks the bartender for 1.00000000000003123939 root beers. Bartender says, I'll have to charge you extra, that's a root beer float. Programmer says, better make it a double then.

A programmer walks into a bar and asks the bartender for 1.00000000000003123939 root beers. Bartender says, I'll have to charge you extra, that's a root beer float. Programmer says, better make it a double then.

Can the code be used for connections through InterNet ? The example you show in here is for local connection (it will cover LAN connections, I suppose). My doubt is if it will work in WAN connections.
And the other question I have is how does the code support multiple simultaneous connections in the same TCP Port. If a client computer connects to the server no other can connect to it simultaneously ?

It is just great. What I am trying to build is an FTP-like server but without the two port problem. Here in Argentina, in little towns there are providers that drop packets (I guess) and our FTP solution often fails. If I can implement your solution through port 80 I think no provider will stop the transfers. I need to transfer small Zip files (no more than 200Kb). Do you think I can manage to use your code fot that ? Do you have another suggestion otherwise ?

First of all, thank you for sharing!
I need to do some async communication from server to client.
This is my scenario: client send a packet with data, server get it and then starts to do some work; when finished, it send a packet with response to the client.
Do you think your project can do it?
Can you point me to the right way to modify your project?
Thanks!

Hi,
If the time between request and response is reasonable (i.e. couple of minutes) you can probably get away with the code as is [possible tweak the send timeouts in the config class].

If not the server processing takes a lot of time, then you could setup a polling mechanism on the client to check the server's progress or you can create a tcp server on you client and have it receive the response from the server when the server has finished [the server sends a packet].

Server implementation actually sends a ReturnPacket istantly after the receive; I will try to implement a Send() method, that server can use to send a packet when necessary. I need also to store and retrieve the right client information when sending packets form server; do you think there's something better (and thread-safe) than a Queue to store clients?
Thank you!

I think you should add some test comparisons, I seeing only the number of requests does not shows me if it is faster than WCF, really faster, or has an equivalent speed. Also, I think you should explain a little how the classes were created, and not only how to use them.

Paulo, what do you mean by "pure TCP/IP"? You see, there is no such thing. To do some benchmarks, you will need to create some data structure, some application-level protocol (even it's very trivial, there is always one), send data in smaller of bigger chunks, do something with it. The overall performance will depend on all that.