Click here to Skip to main content
11,925,101 members (52,261 online)
Click here to Skip to main content
Add your own
alternative version


68 bookmarked

C# TCP Server

, 8 Apr 2013 CPOL
Rate this:
Please Sign up or sign in to vote.
A light weight easy to use .NET TCP server library


This article describes a library that provides an easy to use a TCP server component for the .NET environment that does not have the limitations that many .NET TCP server tutorials have.


For one project I worked on the client had a requirement for multiple TCP server interfaces (4 in all), when I googled how to do a TCP Server in C# I found that there wasn't an easy to use TCP server component (like there is in the Delphi/C++ Builder environment) for the .NET framework (TcpListener class does half the job, but there was nothing to manage the connected clients).

None of the C# TCP server tutorials I found were written with the idea of code sharing between multiple TCP servers projects. I also found that all the tutorials had various limitations (some would only support only one connected client, others would create a new thread for each connection meaning the thread limit is the connection limit), so i decided to write my own without these limitations.

Using the code

The source contains 2 projects, TcpServer, and TestApp (TestApp is provided as an example, you can otherwise ignore it). Add the TcpServer project into your solution, after compiling you should find the TcpServer component in the toolbox ready to be placed onto a form, service, component or other container. Alternatively you could manually add the component to the toolbox and use as a component or manually add the project reference, then and call the constructor directly.

To start the TCP server you'll have to call a sequence of code like this;

TcpServer tcpServer1 = new TcpServer(); //in constructor (auto added if added as a component)
private void openTcpPort(int port)
    tcpServer1.Port = port;
private void closeTcpPort()

Calling Open() will open the specified TCP port for listening and start the 2 internal threads that handle the main functions of the TCP server. Conversely Close() stops the 2 internal threads and closes the port, releasing all system resources.

The Port property is the TCP port opened or to be opened, note that changing Port while the port is open could cause some undesired consequences. The property IsOpen will tell you if the port is open before changing it.

There are 3 callback events OnConnect, OnDataAvailable and OnError.

OnConnect is called when a new client connects, OnDataAvailable is called when a previously connected client has something in its buffer ready to read.

Both OnConnect and OnDataAvailable will pass a TcpServerConnection class (which is essentially a slim rap-around for the TcpClient class) that represents the client that connected/has data available.

Both events are called from a thread specifically created for them, neither event will be called again (for that client) while this thread is still active (i.e. when you have multiple callbacks at once it will be for different clients). If there is any data still in the buffer after returning from one of these callbacks the OnDataAvailable event will be almost immediately called again.

Example callback 1;

public delegate void invokeDelegate();
private void tcpServer1_OnDataAvailable(tcpServer.TcpServerConnection connection)
    byte[] data = readStream(connection.Socket);

    if (data != null)
        string dataStr = Encoding.ASCII.GetString(data);

        invokeDelegate del = () =>

        data = null;

protected byte[] readStream(TcpClient client)
    NetworkStream stream = client.GetStream();
    while (stream.DataAvailable)
        //call stream.Read(), read until end of packet/stream/other termination indicator
        //return data read as byte array
    return null;

Example callback 2;

private void tcpServer1_OnDataAvailable(tcpServer.TcpServerConnection connection)
    byte[] data = readStream(connection.Socket);

    if (data != null)
        string dataStr = Encoding.ASCII.GetString(data);

        string reply;

            reply = getReply(dataStr);

        data = null;
As you can from this example the TcpServerConnection has a property called Socket, this is a TcpClient class, so you can use it in the same you would if you were writing a TCP client program (minus the, often messy, reconnection logic).

Also illustrated above, the TcpServerConnection has a sendData() function, this will take a string, which will be converted using a given System.Text.Encoding encoding (ASCII by default), which is queued for one of the TcpServer's internal threads to send down the stream. You can, of course, send data directly using the TcpClient's functions, though if you do it is recommended that you do not use either of the send functions in this library, otherwise it could lead to packets being sent out of order.

The TcpServer's OnError callback is called directly from one of the 2 threads that operate the TCP Server. It is unlikely you will see this event called except in extreme cases (e.g. you've run out of memory). Calls to this event are triggered by unhandled errors, the Exception causing this is passed as a parameter to the event.

The other properties of TcpServer are as follows;

MaxSendAttempts; when calling the Send() function or the TcpServerConnection's sendData() function one of the TcpServer's internal threads will process the actual sending, if an IOException occurs while attempting to send it will retry up to MaxSendAttempts times before discarding the message.

Connections; (read only) this is a list of TcpServerConnections representing all the connected clients. Calling this property will give you a copy of the internal list.

IdleTime; when either of the internal threads detects there is no work to do they will wait for up to this many milliseconds before check again. This value should always be low, there should be no reason to increase it above the default, if you have high traffic then this should be set very low.

MaxCallbackThreads; this represents the maximum number of callback threads to allow at any one time. What this should be depends on how many threads your hardware and version of Windows can handle, and how many other things are running on the server. The default value of 100 is conservative, if you have high traffic you should increase it.

VerifyConnectionInterval; this is how often (in milliseconds) the TcpServer should verify that a client is still connected. The verifying process can take some time so if you have high traffic this should be set high, however problems arise when a client drops out and tries to reconnect before the TcpServer has verified the previous connection (usually leading to the new connection dropping out). I.e. this value is indicative of how long a client that has to wait before they can successfully reconnect. So you should set this to the minimum value you can get away with.

Encoding; Every TcpServerConnection has a property of the same name, which is the System.Text.Encoding used to encode data passed through sendData() or Send(). The property on the TcpServer represents the default for all new connections, by directly changing this on the TcpServer it will change all clients that have the default encoding to the new econding. To change the default without changing the clients use the SetEncoding() function with the changeAllClients parameter set to false. Encoding is Encoding.ASCII by delault.

As noted above, the TcpServer also has a Send() function. It will send the message passed to it to all connected clients (the closest thing to a broadcast you can do in TCP). Calling this is the same as calling the sendData() function on every item in Connections. The string passed will be converted to a byte array according to the Encoding property of each client.


2013-04-08 - Released to CodeProject.

2014-03-11 - Fixed calling close now always correctly clears the connections list (Thanks Bart - Member 10655793).


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Craig Baird
Australia Australia
No Biography provided

You may also be interested in...

Comments and Discussions

QuestionWhy too slow Pin
hiok200020-Nov-15 3:05
memberhiok200020-Nov-15 3:05 
QuestionIPv6 support? Pin
Member 1056870616-Oct-15 9:39
memberMember 1056870616-Oct-15 9:39 
GeneralMy vote of 5 Pin
I-Flite7-Oct-15 4:24
memberI-Flite7-Oct-15 4:24 
Questionconsole mode Pin
EaglePC6-Apr-15 4:21
memberEaglePC6-Apr-15 4:21 
BugReceiving bigger data by TCP Pin
RRM763-Mar-15 5:52
memberRRM763-Mar-15 5:52 
QuestionSetting IP for Server Pin
Zygot7-Nov-14 10:46
memberZygot7-Nov-14 10:46 
QuestionSending to 1 endpoint Pin
Member 1095138816-Jul-14 11:38
memberMember 1095138816-Jul-14 11:38 
AnswerRe: Sending to 1 endpoint Pin
Member 1095138821-Sep-14 11:31
memberMember 1095138821-Sep-14 11:31 
GeneralRe: Sending to 1 endpoint Pin
Member 1001814611-Sep-15 5:55
memberMember 1001814611-Sep-15 5:55 
QuestionSending to 1 connected endpoint Pin
Member 1095138816-Jul-14 10:49
memberMember 1095138816-Jul-14 10:49 
General5 from me. Pin
Brian Oh2-Jul-14 3:48
memberBrian Oh2-Jul-14 3:48 
QuestionGet Listening IP Pin
Member 1056269224-Mar-14 11:36
memberMember 1056269224-Mar-14 11:36 
Questionminor issue Pin
Member 106557939-Mar-14 8:48
memberMember 106557939-Mar-14 8:48 
QuestionApp hangs on Increasing Number of clients Pin
nitin-aem1-Mar-14 1:01
membernitin-aem1-Mar-14 1:01 
Questionvery nice :) Pin
Member 1059323412-Feb-14 22:56
memberMember 1059323412-Feb-14 22:56 
Questionconfiguration for 1000 and more clients Pin
d474230-Sep-13 3:20
memberd474230-Sep-13 3:20 
QuestiontcpServerTester.exe explain Pin
adamrania9-Sep-13 20:08
memberadamrania9-Sep-13 20:08 
GeneralMy vote of 1 Pin
jgauffin16-Apr-13 4:54
memberjgauffin16-Apr-13 4:54 
QuestionWhat is the benefit? Pin
Johan Wolmarans15-Apr-13 13:55
memberJohan Wolmarans15-Apr-13 13:55 
QuestionLooks Really Basic Pin
Matthew Hanna15-Apr-13 13:26
memberMatthew Hanna15-Apr-13 13:26 
QuestionWhich limitations you removed? Pin
Thornik15-Apr-13 12:55
memberThornik15-Apr-13 12:55 
GeneralMy vote of 5 Pin
Qwertie15-Apr-13 10:44
memberQwertie15-Apr-13 10:44 
GeneralMy vote of 5 Pin
Daniel E. Alvarez8-Apr-13 4:35
memberDaniel E. Alvarez8-Apr-13 4:35 
SuggestionWhat thread/connection limitation? Pin
bitterskittles8-Apr-13 1:49
memberbitterskittles8-Apr-13 1:49 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.151125.3 | Last Updated 8 Apr 2013
Article Copyright 2013 by Craig Baird
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid