
This course is for programming professionals who have some programming experience but never tried network programming
Many courses and books about network & socket programming pile up tonnes of theory before the real code. That's not the way programmers do it. I have tried to take a different approach and we will get started with only the essential theory and jump into code ASAP.
I am a rookie coder, I've been out there for so many years and written a lot of code (C++, C# .Net, Java) until so far. Because of my approach, will be in a sound position to write software capable of sending and receiving data over the network before the end of this course.
Download source code from each lecture via the video download icon, the course content tab, or GitHub repositories. Access up-to-date, section-specific client and server source code and slides.
I recorded this course back in 2014, and I still can't quite believe I'm adding a lecture to it in 2026 — but here we are. In this update, I open the original server project in Visual Studio 2026 to confirm it still builds, then use Claude to migrate the solution from .NET Framework 4.5.2 to .NET 10 live, with no code changes required. As I mention in the video, the core System.Net.Sockets API you're learning in this course hasn't meaningfully changed since .NET 4.5 — the concepts you're building here are still exactly what you'll use today.
Once the migration is verified, I open the same project in VS Code, run it with dotnet run, and confirm the server still accepts connections and echoes data back, just like earlier in the course.
The updated, .NET 10-targeted source code is available here: https://github.com/naeemakram/ClaudeDotNet10UpdateTcpSockets
The Host
A computer network is made up of hosts, which are also called nodes. A host can be a laptop, a smart phone, a router, or anything and everything that is capable of connecting to the TCP/IP network.
An Internet Protocol Address is also called IP Address for short. Every host(computer/phone/router etc.) in a computer can be reached by a unique IP Address.
We will use IP addresses conforming to Internet Protocol Specifications version 4 AKA IPv4, a newer version of IP specifications called IPv6 is also available but it is catching up with the widely used IPv4.
An IPv4 address is basicallly a group of four 8 bit numbers. Each number in the group can have a value between 0 to 255.
When printing an IP address the 4 numbers mentioned above are seperated dot character . to make an IP address easily readable.
Note: You may watch the video first and take a look at the description later on if you forget something.
In order to understand port numbers we consider that our PC is an apartment building. This apartment building can be reached using a specific street address. In our case it will be an IP address.
The apartment building is further divided into apartment numbers. Every apartment is identified by a unique apartment number.
Just like apartments a computer contains a large but finite number of ports, each identified by a numeric value.
A single port can be used to read/write or send/receive data by only one process at any time.
When we need to send data to a software process running on another computer or even on the same computere we need to know the IP address of the remote peer and the port number being used by the peer software process.
A combination of IP and port is called an EndPoint.
There are total 65536 ports on a computer. Port numbers from 0 to 1023 are reserved for operating system usage. These are also called well-known ports or system ports.
Note: You may watch the video first and take a look at the description later on if you forget something.
This lecture explains how a server process and a client process work together using TCP/IP stream sockets.
The client and server are two separate processes which might be running on two different computers, or on the same computer.
The server proess must start first and perform an accept connections operation. It will use a specific IP Address & port number AKA EndPoint for this purpose.
The client process will be started afterwards. In order t connect with a server the client process will need to know the IP address and the port number on which the server is listening for incoming connections.
If an attempt to connect fails, an exception will occur in client process.
Connection attempts can fail for various reasons, common reasons of client/server connectivity failure include
Once a connection is established, both client and server can perform read and write or send and receive operations in order to send and receive data. Remember, a peer(server or client) can perform a write data or send operation only when the other end has already performed a read data or receive operation.
The client and server can receive and send data to each other as long as both are running and a network connection is available.
The client or server might close the connection whenever they want. A client or server may exit for any reason.
If one end goes offline, the other end will receive an exception.
This video shows you how to enable Telnet Client Windows utility, telnet will play an instrumental role in section 2 of this lecture.
Telnet is a feature of Windows OS, its disabled on most machines but users might enable it whenever they want.
The goal of this video is to get started with the server side of a TCP/IP client server arrangement.
We will create a program which would accept an incoming connection on the IP address of the PC on which it is running.
We are going to use port number 23000.
I will show you the steps needed to call the Accept method.
Please be informed, that this part of the course does not demonstrate production grade code.
The purpose of this section is to familiarize you with how sockets work in principal.
The production grade code will be shown in later sections of this course.
This object will provide us a means to receive data from and send data to the client PC which just got connected.
Let’s head over to Visual Studio
You can use an older version of VS.
I am just showing off my cool new software
We are going to create a C# console application to achieve the goal described earlier.
I’m going to create a new Windows Console type application and name it “SocketsServerStarter”.
First thing we need to do is add the namespaces related to sockets in the program, which are
System.Net;
System.Net.Sockets;
Inside the main method, I’ll create an object of Socket class.
Socket listenerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
The first parameter means that it’s an IPV4 socket. The other two parameters are self describing.
Next thing, I will create an object of IPAddress.
I’ll assign it the value IPAddress.Any
This means that our socket will be listening for incoming connections on any available IP address on this PC. That can be the loopback IP address 127.0.0.1 or the current IP address shown by the IP config command.
Please don’t get confused by this statement, it will be clarified in next video.
Next, let’s define an IPEndPoint, which is a combination of an IP Address and a port number.
IPEndPoint ipep = new IPEndPoint(addr, 23000);
We passed it the IP address we define above and the port number 23000.
After this, we will bind the socket which we created earlier to the IP End Point which we just created.
This way, our socket will know what IP address and port will it use for its operation.
After this we will call the listen method.
listenerSocket.Listen(10);
The parameter tells the system how many clients can wait for a connection at anytime while the system is busy.
In order to make something happen, we need one final step.
That is to call the Accept method on our socket.
listenerSocket.Accept();
Accept is a blocking operation. It is a synchronous operation.
In this video we run the server side socket program which we wrote last time. We use Telnet Client utility to connect with a server and put a debugger break point to see the effect of our code.
Learn to receive data on a TCP/IP socket in C# .NET by accepting a client, reading into a byte buffer, and handling the received byte count.
In this video I show you how to convert a byte array into an ASCII string.
Sending data back to a client is fairly simple
We need the the client socket to do it.
Please note that we will send data back in byte format.
We can simply echo the stuff sent to us by the client.
In that case, we will be able to reuse the byte array buff along with the local variable client.
The will be client.Send(buff);
And let’s put this part of our code in a while loop.
Right above numberOfReceivedBytes I will add a while(true) and an opening bracket.
And right after client.send I will add the closing bracket
Let us clean the byte array buffer so that I can receive fresh data every time.
Array.clear(0, buff.length);
numbereOfReceivedBytes = 0;
One last thing, there has to be some way to end this infinite loop here. Right?
So, right after client.send(buff) I am going to add an if statement.
if(receivedText == “x”) {break;}
And we’re done here.
Let’s take a look at the change we made again.
In the next video I’ll demonstrate it. And after that I will show you how to deal with the firewall.
And how we can send or receive data to and from another device, like my Android smart phone.
Do watch the upcoming videos, they’ll be really juicy!
"Nothing is more fun than watching your own code run." Of course this is the height of my poetic skills.
In this video we will run our server side script and see how it is going to rock and roll by by echoing data back to the client.
Windows Firewall is a security component of Windows Operating System.
If it is turned on, it allows only a specific set of application software to use network for communication.
In case of our socket application, if it tries to communicate with an app running on another device over the network, Windows Firewall is going to block it right there. Because it is turned on at my PC.
The firewall works based on user defined rules.
We can tell it using rules what applications to block and what to allow
Let us open Windows Firewall and add rules to allow our sockets application to communicate.
Open Control Panel
Search for “Firewall”
Click the Windows Firewall link
Click “Advanced Settings” link
Click “Inbound rules”
Click “New rule”
Select “Program” radio button and click “Next”
Click “Browse” button
Go to the path of our project debug folder and select “SocketServerStarter”
Click “Next” and select “Allow the connection”
Click “Next”, don’t change anything and click “Next” again
Supply a name here and some description too. Click “Finish”
Now let’s click the “Outbound” item in tree and add a rule here too.
It is possible to send data to this machine from a telnet terminal running on any other machine on the same network.
For example, we can use another PC for this purpose or my Android smartphone.
Let me show you my phone screen.
I have installed this free app on my phone.
Its name is “Telnet Client”. And no this is not a sponsored advertisement!
Here’s their Google Play store listing
I am going to open this app
On my laptop, I will run our sockets application
It will show an “Allow Access” dialog first time. Click the button “Allow Access”.
And I will click the button “Connect”
In here, I need to supply the IP address of my laptop.
The IP address keeps changing because it is assigned by the DHCP in my home router.
Let’s find it quickly.
So the IP address is 192.168.10.5 and in port number I will put 23000
Over here you can see I can simply send anything I like.
This telnet client is different from Windows telnet client in that we can send more than one bytes of data here.
Let’s have a conversation here.
Looks cool
Now I’m going to go to our server window and type Ctrl C to close the application.
One last thing,
The name of my PC is shows NWING in the IP configurations here.
Instead of looking for the IP address again and again, I can use this piece of information here.
For example. Let’s run the telnet client app on Android again and try connecting to NWING on port 23000.
Working with sockets on the client side is fairly similar to to the stuff we have seen in the server side example.
Let me tell you some of those before we start cranking out code. [change slide]
One major difference is that the client sockets don’t do the bind/listen/accept method calls.
Instead, the client sockets perform a connect method call.
In case of TCP/IP, the client socket must know the IP address and port number on which it is supposed to connect.
In case of UDP sockets, there are some other possibilities, but that’s not the subject of this course.
If the client and server are running on the same machine, we can use the loopback IP address 127.0.0.1 to make our lives easier.
I’ve done socket programming on Android too, that means I can teach that too if people are interesting.
I’d be curious to know if you would like to see an Android example too
Anyways, I digress. I’m Sorry :)
Let’s open Visual Studio and create a new console application.
I’ll call our application SocketClientStarter
Inside the code, the first thing I’ll do is add namespaces needed for socket programming
Using System.net
Using System.net.sockets
Inside the main method, I’ll define a socket client variable
Socket client =
New socket(
I’ll use the constructor with three parameters
AddressFamily.InterNetwork is for IPV4
SocketType.Stream is for streaming socket
ProtocolType.Tcp is for TCP sockets
We’re going to need the IP Address of our server, let’s define it here and assign it a null for now.
Ipaddrserver = null;
On the next line, let’s define a try/catch block to handle failure scenarios.
catch(Exception excp)
{
Console.WriteLine(excp.ToString());
}
Inside the try block I’ll define a new string and call it strServerIPInput and assign it the value input by user from console.
Let’s give our users a clue about what they’re supposed to do here one line above.
Console.WriteLine("*** Welcome to Socket Client Starter Example by Naeem Akram Malik ***");
Console.WriteLine("Please Type a Valid Server IP Address and Press Enter: ");
Also define a string to take port number input from user.
string strPortInput = Console.ReadLine();
And some help for users
Console.WriteLine("Please Type a Valid Server Port Number(Integer Only, max 65535) and Press Enter: ");
And an int to store the port number int after parsing it.
Now let’s parse the string given by the user into an IP Address.
IPAddress.TryParse(strServerIPInput, out ipaddrserver);
Add an if condition here in case of bad user input.
if(!IPAddress.TryParse(strServerIPInput.Trim(), out ipaddrserver))
{
Console.WriteLine("Invalid server IP supplied.");
return;
}
We’ll do the same for the port number too.
if(!int.TryParse(strPortInput.Trim(), out nPortInput))
{
Console.WriteLine("Invalid port number supplied, return.");
}
The tryparse functions will return false if they fail to parse the supplied strings according to their type specifications.
We also know that a valid port number has to bee greather than zero and smaller than 65535. So, let’s add an if condition to handle that too.
if(nPortInput <= 0 || nPortInput > 65535)
{
Console.WriteLine("Port number must be between 0 and 65535.");
return;
}
Let’s show the stuff on screen too
System.Console.WriteLine(string.Format("IPAddress: {0} - Port: {1}", ipaddrserver.ToString(), nPortInput));
Next, we’ll call the client socket connect method.
client.connect(
We can supply it a new IPEnd point, or use a constructor which takes IP Address and Port directly.
Let’s use the second one:
And supply IP Address & Port
client.Connect(ipaddrserver, nPortInput);
Console.Writeline(“Connected to server.”);
Add a console.ReadKey() on next line.
Please note that this is a blocking call and it will fail after a timeout period if the server is not running.
Let’s try to run it right away without running the server first.
I’ll press control F5
Input IP Address . 127.0.0.1
Input port number 23000
It fails after a brief pause
An exception is thrown on line number 47, that’s where we try to connect with server.
So now let’s go to our server project and start the server first.
So here you see,we’re connected to the server.
No data will be sent/received right now.
We’ll need to add some send/receive logic to our client program to do that.
Now let’s close the server and go.
Writing some safe code to input server IP and port. Show use of IPAddress.TryParse and int.TryParse.
In the end we perform an Connect method call and see how it works with the Server which we have written so far in this course.
Also show you the poser of Ctrl + . to import missing namespaces into the solution.
How to perform send and receive operations on client side sockets.
Run the final version of code produced in this section and see how it goes. Make minor changes in the client and server to prevent the applications from crashing.
How to handle closing of a TCP/IP client socket in a console application upon application closing. Using the ConsoleEventDelegate of kernel32.dll through interop.
Summary of the things which we learned in this section.
TCP/IP Sockets On Server Side
§How to setup a server socket(Bind and Listen)
§The IPAddress.Any constant
§Accept a connection on the server
§Using telnet client utility
§How to Receive and Send data
§Encoding.ASCII to convert byte[] to string
§Clearing the byte array
§Setup Windows Firewall allow
connecting to my phone
TCP/IP Sockets On Client Side
§Why we need to know server IP & port
§Parsing an IP Address safely
§How to connect to a server
§How to Receive and Send data
§Encoding.ASCII to convert string to byte array
§How to shutdown/close/dispose a socket
§Using try/catch to prevent crashes
Did do it wrong?
§I’m going too fast?
§Did I miss something, just let me know
§Feel free to ask questions in Q&A section
§Source code in lecture downloads area
§I would love to add more videos here
We are going to get into some exciting production grade stuff in this section.
First of all I will show you how to create non-blocking socket applications using async and await keywords. We’ll start on the server side.
The async/await keywords and relevant methods were introduced in .Net Framework 4.5. So you need a version of visual studio which supports it.
Secondly, we will move on from raw sockets and start using helper classes.
For example, instead of using a socket object to accept incoming connections, I am going to show you how to use a TCPListener.
And instead of using a Socket class object to represent the client, I am going to use TCPClient class object.
I am also going to show you how to use StreamReader and StreamWriter with network streams.
Yet another wonderful thing is that we’ll create a class library now onwards in this course.
This approach will make the end result of taking this course much more useful my for students.
Let us create a new WinForms Project.
I’ll pick Visual C# => Windows Classic Desktop => Windows Forms App(.Net Framework)
I’ll call it, UdemyAsyncSocketServer
Let’s add a new class library to house the logic of our sockets stuff
Right click the solution in solution explorer and select Add => New Project.
I’ll select Visual C# => Windows Classic Desktop => Class Library(.Net Framework)
I’ll name the library “LahoreSocketAsync”
Lahore is the wonderful city where I live
Click the Class1.cs file and press F2 to rename it to “LahoreSocket.cs”
Click “Yes” when VS asks you if you want to rename the auto generated class too.
First of all, we need to supply an IP address and a port number when a server needs to listen for incoming connections.
Let’s define those in our class.
IPAddress mIP;
int mPort;
Click IPAddress and press Ctrl+.
Click “Using System.Net”
Next, let’s define our first method
I’ll call it
public void StartListeningForIncomingConnection(IPAddress ipaddr = null, int port = 23000)
This method will allow the caller to specify an IP Address and a port.
Default values of these parameters are in place for convenience.
Now I need you to pay attention, just in case you’re doing something else alongside watching the videos.
I do it all the time.
We need to add the keyword async before the return type of our method.
This is mandatory if we want to make an async call inside the body of this method.
We are going to use an asynchronous method of a TCP/IP helper class inside this method.
Inside the method, let’s add some code to see if parameters supplied are ok or not.
if(ipaddr == null)
{
ipaddr = IPAddress.Any;
}
if(port <= 0)
{
port = 23000;
}
mIP = ipaddr;
mPort = port;
Let’s print the final values to the debug output
System.Diagnostics.Debug.WriteLine(string.Format("IP Address: {0} - Port: {1}", mIP.ToString(), mPort));
Now let’s introduce a variable of type TCPListener.
TCPListener is a .Net framework helper class which makes TCP/IP programming on the server side easier.
mTCPListener = new TcpListener(mIP, mPort);
The system is showing us some squiggles, let’s fix them.
Click TcpLiseneter constructor and press Ctrl+.
Select appropriate socket namespace to add.
Click mTCPListener and press Ctrl+.
Click “Generate field in LahoreServer” option
Now let’s call the start method of our TCPListener.
mListener.Start();
Next, we’ll make the async call
mListener.AcceptTcpClientAsync();
If we hover the mouse on the method, we’ll be able to see more details about it.
The usage section below says we need to put the async keyword behind the method call.
If we take a look at the definition of our method, it also shows a green squigly complaining that we need to await this method.
Let’s introduce the await keyword here, right before the accept call.
Now put the return value in a variable too
var returnedByAccept =
Let’s write some information to the debug console too
I’ll put a breakpoint after the acceptTcpClientAsync as well.
We are going to use the value returned by this method in an upcoming video.
The important point you need to understand is that when the .Net Framework will see the await keyword inside a method which has got async in its definition, it will generate some code behind the scene to make sure things happen in an async manner.
Once the asyc operation is finished, your code will resume execution beyond this point.
Now I’ll go back to my Forms project and add a reference of LahoreSocketAsync.
I’ll go to the Form design view and add a button, I will name it btnStartServer
Double click the button
Go to the top and add a using statement to bring in LahoreSocketAsync
Inside the form class, I’ll create a reference of LahoreServer
LahoreServer mServer;
We’ll instantiate this member variable in form constructor
mServer = new LahoreServer();
Now let’s go back to button click method and start accepting incoming connection request
mServer.StartListeningForIncomingConnection();
Let’s run the code in next video and see the affects of the work we’ve done so far.
Demonstration usage of AcceptTcpClientAsync method call to listen for incoming connection requests for non blocking I/O without spinning extra threads in your code.
Implement a continuous accept loop in the socket server by wrapping the listener start in a try-catch for exception handling, using keep running flag, and handling each accepted TCP client.
In order to perform async read operation in method TakeCareOfTCPClient, we need to make it async.
Let’s add the keyword async to the method definition
Inside the method, I’ll define a variable of type NetworkStream and assign it null for now.
NetworkStream stream = null;
I’ll also add a variable of StreamReader type too.
Every TCP/IP stream socket has got an I/O stream attached to it.
Just like the stream available in case of console I/O or file I/O.
We will use the StreamReader to read data from the network stream associated with the TcpClient passed into this method as a parameter.
After that let’s create a try catch block
try
{
}
catch(Exception excp)
{
System.Diagnostics.Debug.WriteLine(excp.ToString());
}
Inside the try block, I’ll assign the network stream object a value.
stream = client.GetStream();
I’ll assign the stream reader object a value based on the network stream
reader = new StreamReader(stream);
In order to read data sent from the client through stread reader, we’ll define an array of char
char[] buff = new char[64];
Now we’ll create a while loop
while (keeprunning)
{
}
Let’s write info on debug that we’re ready to read
Debug.WriteLine("*** Ready to read");
After this, we’ll call an async method on stream reader.
We will start with the await keyword
await
reader.ReadAsync(buff, 0, buff.Length);
If we hover the mouse on the call to ReadAsync, we can see that it returns a Task<int> and the usage tells us we can store return value in int.
Let’s define a variable and store the values here.
We’ll also print the number of received bytes to the screen
System.Diagnostics.Debug.WriteLine("Returned: " + nRet);
On the next line, we’ll see if the return value is zero.
When this method returns zero, it means the socket connection has been closed.
In this case, we’ll print a debug log and break the loop.
if (nRet == 0)
{
System.Diagnostics.Debug.WriteLine("Socket disconnected");
break;
}
In case you are wondering “wait, why the Debug.Writeline?”
Rest assured, we’ll take good care of these messages later in this course.
Next, we’ll convert the received character array into a string
string receivedText = new string(buff);
And print it to the debug console
System.Diagnostics.Debug.WriteLine("*** RECEIVED: " + receivedText);
Before we could start the next read operation, we also need to clear the byte array buffer which we use for receiving data.
Array.Clear(buff, 0, 64);
Now build the solution and make sure it compiles
That’s it, in the next video we’ll run our server application with the client application which we created in the last section.
Read data from a network stream in C# .Net using asynchronous StreamReader method calls.
Learn to manage a server-side list of connected tcp clients, automatically add on connect, remove on disconnect, and broadcast a message to all clients asynchronously.
Demonstrating a server that handles multiple clients via a sendAll method, this demo shows client connections, counts, and sending a message to all connected Telnet clients (not a true broadcast).
How to stop the server and disconnect the client sockets properly
In order to stop the server properly, we’ll need to do two things.
First, stop the TCPListener from accepting new incoming connections.
And second, disconnect all connected clients.
We’ll add a method StopServer to our library to do this.
In this video, I’m going to show you how to do these steps.
Let’s head over to the visual studio
I’ve opened the socket server project
First, I’ll add a button on the Form. I’ll name it btnStopServer and set text to Stop Server.(do form resize and button addition faster).
Double click the button
Inside event handler, I’ll use the object mServer to call a method which does not exist yet.
I’ll say mServer.StopServer()
Now I’ll press Ctrl+. to generate the method and press F12 to go inside of it.
First thing, Let’s add a try catch block.
Inside the try/catch set KeepRunning to false.
Next, if(mTcpListeners != null){}
mTcpListener.Stop();
By doing this, we’ve stopped the listener from accepting new connections.
But, we still have the socket connections open which mean we can still receive/send data.
Let’s go through the list of connected clients and close them one by one. We’ll also remove them from the list.
foreach(TcpClient c in mClients)
{
c.Close();
}
After the loop, we’ll clear the list
mClients.Clear();
We can call this method on the Form OnClosing event too.
I’ll go to the form designer view and open Properties pane.
Click “Events” thunderbolt
That’s it, we’re done. We’ll be able to start and stop our server any time we want after this implemenation.
Let’s run it in the next video.
Demo: Stop TcpListener and Close client sockets
I will start our server program and click button “Accept Incoming Connections”
Launch a few clients by pressing Windows + R and supplying the telnet command.
You can see we’re sending data back & forth.
Now if I go ahead and click button Stop Server
You will see that the telnets will close(will have to click the telnet windows)
I can go back and start the server again by clicking the button “Accept Incoming Connections”
And launch a few telnets once again
If I type text on these telnet terminals, you’ll see it reaches across to the server.
And, if I try to send text to all clients, that too is going to work fine. (Click button Send All on server)
This means, that starting and stopping multiple times does not have a bad affect of our server.
Now let’s see what happens if I have stopped the server.
I’ll click the button “Stop Server” once again.
And try to connect a Telnet client to it.
You see, the telnet can’t find our server.
Why? Because we called the TcpListener.Stop method when we click the button “Stop Server”.
That’s the reason the server does not listen for new incoming connections.
Now you know how to stop the tcp listener from accepting new connections and how to do away with the tcp client objects too.
Section Summary: Asynchronous Socket Programming
Let’s quickly recap the useful things we learned in this section.
In this section, we got started using async and await keywords along with some special async socket I/O methods.
We learned how to accept incomi ng connections using socket helper class TcpListener.
We used the method AcceptTcpClientAsync() to accept connections in a non blocking way
After that, we saw how we can continuously listen for incoming connections and how to handle exceptions in the async method of our class library.
Without impeding the operations.
We also came to know about the TCPClient helper class, which makes client side socket programming easier.
Then we went on to use the ReadAsync method of the network I/O stream using an object of StreamReader.
Not to mention that this too is an asynchronous method, which doesn’t block our application.
Afterwards, we wrote the logic to maintain a list of clients connected to our server.
This list was used to send data to all connected clients using WriteAsync method of NetworkStream attached to the instance of the socket which is attached to our TcpClient.
In the end, I showed you how to stop the server properly by calling the Stop method on the TcpListener and how to disconnect a socket by calling Close method on a TcpClient.
I hope you would’ve found this section useful. Feel free to ask questions in Q&A section.
You can clone or fork the public repositories of this library on GitHub. It’s all yours to modify, improve, and play.
If you think this course has been useful, this course has added value to your life, please leave a positive rating and review.
Next section, we’ll create the client application using async calls.
Hi, in this video we’re going to setup a project to create the async client side software of a TCP/IP client server arrangement.
We’re going to add another class to our library LahoreSocketAsync for this purpose.
This work will be done in a console application, to take down two birds with one stone.
We’ll create a new C# console application solution and project and then add the existing library to it.
The server and client solutions refer to the same library, but I’ve kept the solutions separate intentionally.
This is going to make our life easier when we’ll be debugging.
Let’s get started(<do> create project here)
I’ll add a the existing socket library project to this solution
In the solution explorer, I’ll right click the solution and select Add => Existing Project
I’ll go to UdemyAsyncSocketServer folder and go to LahoreAsyncSocket folder
Add LahoreSocketAsync project
Right click LahoreSocketAsync project and select Add => New Item
Select “Class” And name it “LahoreSocketClient”
All right, we’re cool here. In the next video, we’ll some logic to connect with a server and start reading data.
In this video, we’re going to call the async method TcpClient.ConnectAsync to connect with the server.
We will also add the member variables needed to represent the server IP Address, server port number, and the TcpClient object.
In order to make the class available publicly, we will add public access specifier to our client class name too.
I’ve opened the socket client library project.
First thing, I’ll add member variables to class LahoreSocketClientAsync to store server IP and port.
IPAddress mServerIPAddress;
Click red squigly, click light bulb, and click “Add System.Net;”
int mServerPort;
We’re going to use a TcpClient helper class to connect with the server. Let’s declare it at the class level.
TcpClient mClient;
Add relevant namespace using System.Net.Sockets;
I want to declare class constructor to set default values of these members here.
Ctor double tab
mClient = null;
mServerPort = -1;
mServerIPAddress = null;
Now Let’s create getters for these members.
The setters will be a little different. I want to return false if the user supplies an invalid IPAddress or Port values.
Let me define a new method here
Let’s create a similar method for the port number too.
public bool SetPortNumber(string _ServerPort)
Now comes the heart of this video, the async method ConnectToServer.
public async Task ConnectToServer()
{
}
This method is declared to be async because we’re going to make an async method call inside of it.
The return type Task is essentially equivalent to void.
The MSDN says we should use async Task instead of async void for async methods. Going into the details will be beyond the scope of this course.
Now let’s add the method
public async Task ConnectToServer()
{
}
If mClient is equals to null, we’ll assign it a new instance.
if(mClient == null)
{
mClient = new TcpClient();
}
We’ll use the constructor without parameters.
Let’s add a try/catch block for safety sake
And then, we
’ll call the method mClient.ConnectAsync
We’ll supply this method with the IPAddress of the server and the port number.
Await mClient.ConnectAsync(mServerIPAddress, mServerPort);
Console.WriteLine(string.Format("Connected to server IP/Port: {0} / {1}", mServerIPAddress, mServerPort));
This is it, we’re in good shape. We’ll add the logic for reading data from the socket network stream in the next video. We’ll also call these the newly added in our console application and have a demo afterwards. See you in the next video!
Add the LahorSocketAsync library to a console app, create a LahorSocketClient, and configure server IP and port. The demo tests async connect, reads inputs, and exits on 'exit'.
In this video, we’re going to write code to read data sent down from the server to our client.
2. The receive operation is going to be exactly the same like we saw in the server side video previously
3. I’ll go inside the LahoreSocketClient class dot c s file.
4. In the ConnectToServer method, I’ll go to the point after the method call
5. await mClient.ConnectAsync(mServerIPAddress, mServerPort);
6. We need to add three local variables here
i) A streamreader to read data off the network stream of our TcpClient object
ii) A char array to store the data sent by the server
iii) And an int to store the number of characters read in
7. Let’s declare the variables
9. You can see that we’ve called the constructor of StreamReader and passed it the result of mClient.GetStream() method.
10. This method is going to return the network stream associated to the instance of our TcpClient.
11. A network stream is attached to every socket and every TcpClient to perform I/O operations.
12. I’ll click the StreamReader and press Ctrl+. And click using System.IO; to bring in the relevant namespace.
13. Now add an infinite while loop which will end only when the connection is broken from the server.
17. Inside this loop, I’ll call the ReadAsync method of our stream reader.
18. await clientStreamReader.ReadAsync(buff, 0, buff.Length);
19. This method is going to return the data sent by the server in the first parameter, which is the char array buff.
20. We’ve told the method that it can start putting data in the output buffer starting from zero and ending at the length of buffer.
21. Let’s put the return value in the readByteCount variable.
23. If the read byte count is ever less than equal to zero, that means the connection with server has been broken.
24. We’ll put this fact in code
We will need to close the client before moving forward.
25. And now write the result to the console.
26. Console.WriteLine(string.Format("Received bytes: {0} - Message: {1}", readByteCount, new string(buff)));
27. Before we start reading data again, we need to clean the buffer.
28. Array.Clear(buff, 0, buff.Length);
29. This is it, we’re all set for receiving data too.
30. We’ll have a demo in the next video!
Demonstrates asynchronous client-side TCP/IP socket programming in C# .NET, connecting to loopback 127.0.0.1:23000, reading data non-blockingly, and gracefully restarting or closing the client as the server sends data.
1. Sending data to the server is again, a fairly simple task.
Just like everything else in this course.
2. We will use an object of stream writer to write data on the socket connected to our instance of TcpClient.
3. Needless to say, we’ll do it in a non-blocking way and add an async method to our client class.
Let’s open the client project in visual studio.
4. We’ll head over to the main method in the console application.
5. Inside the do while loop, we can send the input data to the server if user input is not equal to <EXIT>
if(strInputUser.Trim() != "<EXIT>")
{
}
6. Inside the if condition Let’s call an arbitrary send method on the client object.
7. We’ll define this method later on.28-Read data on stream reader
8. client.SendToServer(strInputUser);
9. Now I’ll click the method call SendToServer and press Ctrl+.
10. And select Generate method
11. Next, I’ll press F12 and go to the method definition
12. The default implementation is throwing NotImplementedException, let’s remove it
13. We also need to add the keyword async to the method signature to make it non blocking
14. Let’s do it
15. And as you remember I told your earlier, we must never put async void in a method signature.
16. Instead, we should use async Task
17. Inside of this method we can simply check if the mClient is not null and if it’s connected.
if(mClient != null)
{
if(mClient.Connected)
{
}
}
18. I also don’t want to do anything when the user has supplied a null or empty parameter. Let’s put this in code too.
19. We’ll do it at the top section of the method.
20.
if (string.IsNullOrEmpty(strInputUser))
{
Console.WriteLine("Empty string supplied to send.");
return;
}
21. Now let’s create an instance of a stream writer to send data.
StreamWriter clientStreamWriter = new StreamWriter(mClient.GetStream());
clientStreamWriter.AutoFlush = true;
24. Auto flush is an important property.
25. This means that as soon as one write operation is finished, the data should be flushed over to the other end of stream.
26. And that is just it!
27. Let’s have a short demo in the next video.
Demonstration, writing data on TcpClient network stream.
else if(strInputUser.Trim().Equals("<EXIT>"))
{
}
client.CloseAndDisconnect();
if(mClient != null)
{
if (mClient.Connected)
{
mClient.Close();
}
}
Demo of how to close a TCP/IP client side connection properly.
§Setup a new solution for client side network programming
§Added a new class to the library
§TcpClient.ConnectAsync method call
§Read data with StreamReader.ReadAsync method call
§Write data with StreamWriter.WriteAsync method call
§Close a connection with TcpClient.Close method call
Adding a ClientConnected event to the publisher library and handling it in the subscriber side as well.
Time to publish another event in our socket library. This time we'll add a TextReceived event on the server and display the information in a Forms text box.
How to publish a TextReceived event in client side classes.
I’ve added following events to the class library along with usage code as well.
Client Library Events
public EventHandler<ConnectionDisconnectedEventArgs> RaiseServerDisconnected;
public EventHandler<ConnectionDisconnectedEventArgs> RaiseServerConnected;
Server Library Events
public EventHandler<ConnectionDisconnectedEventArgs> RaiseClientDisconnectedEvent;
Please download the zip file attached in the downloads section of this lecture and take a look, it will be utilized in the next section(in the making at present).
Finding IP Address of Your PC
We will use command prompt to find the IP Address of your PC.
The graphical user interface is different in case of different versions of the Windows operating system, but the good old command prompt remains unchanged.
So, let’s launch command prompt.
Press Windows + R
Type cmd
Click OK
The command we’re going to use is ipconfig with option forward slash all.
I’ll type it on command prompt
Ipconfig space forward slash all
And press enter
The information related to ip configuration of your machine will be printed
Information related to the IP address to your machine while its running on the WiFi is grouped under “Wireless LAN adapter Wireless Network Connection”
The IP Address is printed in front of IPv4 Address
If your machine is connected to the network through an ethernet network cable, the information will be grouped under “Ethernet adapter Local Area Connection”.
Right now, my machine is not connected to an ethernet cable that’s why not much information is displayed here.
It is possible to dump the output of a command prompt command to a text file.
We can use the greater than sign operator for this purpose.
Let’ me show you, I’ll type the same IPConfig command again.
Add a greater than sign, a space and supply the text file name where we want to dump the output.
I’ll name the file ipc.txt
And press enter
Let’s open the file explorer in current directory to see the file.
I’ll type explorer space and a dot
Press enter
We can see the file ipc in the file explorer, let’s open it.
All IP configuration information of your PC is printed here.
The IP Address is printed under Wireless LAN adapter wireless network connection.
The DHCP and DNS play a key role in modern computer networks.
DHCP stands for Dynamic Host Control Protocol
DNS stands for Domain Name Server
Let me tell you more about the “dynamic duo” of computer netwoks
The Dynamic Host Control Protocol is implemented by a piece of software mostly built into devices like home routers.
The job of DHCP server is to assign an IP address to every device that joins a network and configured to work with DHCP.
Once an IP address is assigned to a host dynamically, the job of DNS starts.
The Domain Name Server keeps track of the IP addresses of all hosts on the network.
The DNS can be used to lookup IP addresses of any host on the network using the host name
The DNS is built into every home router, just like its friend DHCP
In the next video I’ll show you how to get the IP Address of a host by hostname programmatically using the .Net DNS class.
Demo of how to find IP Address of a HOST by using System.Net.Dns class.
Since you've come this far in TCP/IP Socket Programming, I'm pretty sure you'd love to learn more about the twin brother of TCP/IP sockets. Yes, I'm talking about UDP Sockets.
Get proficient in computer network socket programming using TCP/IP streaming sockets and become a better professional programmer. This course starts you with TCP/IP network programming using the C# .NET socket library, and gets you writing real code fast.
2026 update — the Section 1 server code, verified on .NET 10. This course was originally recorded in 2014, and the core System.Net.Sockets API you're learning hasn't meaningfully changed since .NET 4.5 — that's exactly why it's still relevant over a decade later. In a new lecture, I open the original Section 1 server project, confirm it still builds in Visual Studio 2026, then use Claude to migrate that project live from .NET Framework 4.5.2 to .NET 10, with no code changes required. I then run it from VS Code with dotnet run and confirm it still accepts connections and echoes data back, exactly as it did in the original recordings. The point isn't that every project in the course has been rebuilt for .NET 10 — it's that the sockets concepts at the heart of this course are proven to still hold up, unchanged, on the current runtime. The updated Section 1 source is available on GitHub, linked directly in the lecture.
Each video in this course covers one essential concept of client-server socket programming and network communication. Ready-to-use C# code examples are supplied as downloadable Visual Studio solutions. After every few lectures, a demo shows the practical implementation of what was just described.
By the end of this course, you'll be able to build C# .NET software that sends and receives data over TCP/IP sockets, peer-to-peer, using async and await. You'll learn not just socket programming, but the same non-blocking I/O pattern used in production .NET networking code today.
Why this still matters in 2026. AI coding assistants can generate socket code that compiles and runs. What they're far less reliable at is explaining why a given pattern is correct, or helping you reason through a race condition in a multi-client server at 11pm. This course builds the actual mental model — sockets, ports, endpoints, blocking vs. non-blocking I/O — the part of the skill that doesn't get automated away and still shows up in networking interview questions.
Minimum upfront theory. Many courses pile up theory before the real code. This one doesn't — you'll be writing C# socket code within the first 15 minutes.
Who this course is for: developers and CS/university students with some C#, Java, or C++ experience who've never worked at the socket level. If you can write code but have never had to reason about ports, streams, and async network I/O, this closes that gap directly — with a project-based, WinForms-first approach instead of bare console demos.
Over 11,000 students have taken this course, many while working through university distributed-systems assignments or preparing for networking interview questions.