C# > Networking > HTTP and Sockets > TcpClient and TcpListener
Simple TCP Server and Client with TcpListener and TcpClient
This example demonstrates a basic TCP server and client application using TcpListener
and TcpClient
in C#. The server listens for incoming connections, and the client connects to the server, sends a message, and receives a response.
Concepts Behind the Snippet
TcpListener
is used on the server-side to listen for incoming TCP connections on a specified port. TcpClient
is used on both the client and server to establish a TCP connection. The NetworkStream
is then used to send and receive data over the established connection. This snippet uses synchronous operations for simplicity; real-world applications often employ asynchronous methods for better performance.
TCP Server Code
This code creates a TcpListener
that listens on a specific port (13000 in this example). It accepts incoming connections using AcceptTcpClient()
, reads data from the client using a NetworkStream
, converts the received data to uppercase, and sends it back to the client. Error handling is included to catch potential SocketException
errors, and the server stops listening when finished.
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
public class TcpServer
{
public static void Main(string[] args)
{
TcpListener server = null;
try
{
// Set the TcpListener on port 13000.
Int32 port = 13000;
IPAddress localAddr = IPAddress.Loopback; // Or use IPAddress.Any to listen on all interfaces
// TcpListener server = new TcpListener(port);
server = new TcpListener(localAddr, port);
// Start listening for client requests.
server.Start();
// Buffer for reading data
Byte[] bytes = new Byte[256];
String data = null;
// Enter the listening loop.
while (true)
{
Console.Write("Waiting for a connection... ");
// Perform a blocking call to accept incoming connection.
TcpClient client = server.AcceptTcpClient();
Console.WriteLine("Connected!");
data = null;
// Get a stream object for reading and writing
NetworkStream stream = client.GetStream();
int i;
// Loop to receive all the data sent by the client.
while ((i = stream.Read(bytes, 0, bytes.Length)) != 0)
{
// Translate data bytes to a ASCII string.
data = Encoding.ASCII.GetString(bytes, 0, i);
Console.WriteLine("Received: {0}", data);
// Process the data sent by the client.
data = data.ToUpper();
byte[] msg = Encoding.ASCII.GetBytes(data);
// Send back a response.
stream.Write(msg, 0, msg.Length);
Console.WriteLine("Sent: {0}", data);
}
// Shutdown and end connection
client.Close();
}
}
catch (SocketException e)
{
Console.WriteLine("SocketException: {0}", e);
}
finally
{
// Stop listening for new clients.
server.Stop();
}
Console.WriteLine("\nHit enter to continue...");
Console.Read();
}
}
TCP Client Code
This code creates a TcpClient
that connects to the TCP server at a specified address and port (127.0.0.1:13000 in this example). It sends a message to the server using a NetworkStream
, receives a response, and displays both the sent message and the received response. Exception handling is included for potential ArgumentNullException
and SocketException
errors. Finally, the client closes the stream and the connection.
using System;
using System.Net.Sockets;
using System.Text;
public class TcpClientExample
{
public static void Main(string[] args)
{
try
{
// Create a TcpClient.
// Note, for this client to work you need to have a TcpServer
// connected to the same address as specified.
TcpClient client = new TcpClient("127.0.0.1", 13000);
// Translate the passed message into ASCII and store it as a Byte array.
Byte[] data = Encoding.ASCII.GetBytes("Hello from client!");
// Get a client stream for reading and writing.
NetworkStream stream = client.GetStream();
// Send the message to the connected TcpServer.
stream.Write(data, 0, data.Length);
Console.WriteLine("Sent: {0}", "Hello from client!");
// Receive the TcpServer.data.
// Buffer to store the response bytes.
data = new Byte[256];
// String to store the response ASCII representation.
String responseData = String.Empty;
// Read the first batch of the TcpServer response bytes.
Int32 bytes = stream.Read(data, 0, data.Length);
responseData = Encoding.ASCII.GetString(data, 0, bytes);
Console.WriteLine("Received: {0}", responseData);
// Close everything.
stream.Close();
client.Close();
}
catch (ArgumentNullException e)
{
Console.WriteLine("ArgumentNullException: {0}", e);
}
catch (SocketException e)
{
Console.WriteLine("SocketException: {0}", e);
}
Console.WriteLine("\n Press Enter to continue...");
Console.Read();
}
}
Real-Life Use Case
This type of TCP client/server setup can be used in various applications, such as: * **Chat Applications:** Real-time communication between users. * **Game Servers:** Handling player connections and data exchange in online games. * **Data Streaming:** Sending sensor data or other information from devices to a central server. * **Remote Control:** Controlling devices or software on a remote computer.
Best Practices
When working with TCP connections, it's important to consider these best practices:
* **Asynchronous Operations:** Use asynchronous methods (e.g., AcceptTcpClientAsync
, ReadAsync
, WriteAsync
) to prevent blocking the main thread and improve responsiveness, especially in server applications that handle multiple clients.
* **Error Handling:** Implement robust error handling to catch exceptions like SocketException
and handle them gracefully. Log errors for debugging and consider implementing retry mechanisms.
* **Resource Management:** Always close streams and clients properly using Dispose()
or using
statements to release resources.
* **Security:** If you are transmitting sensitive data, use encryption (e.g., SSL/TLS) to protect the communication.
* **Keep-Alive:** Consider implementing TCP keep-alive messages to detect and handle broken connections.
* **Connection Pooling:** If your application frequently creates and closes TCP connections, consider using connection pooling to improve performance.
Interview Tip
Be prepared to discuss the difference between TCP and UDP. TCP provides reliable, ordered delivery of data, while UDP is a connectionless protocol that does not guarantee delivery or order. TCP is suitable for applications that require reliable data transfer, while UDP is often used for streaming or gaming where some data loss is acceptable.
When to Use Them
Use TcpClient
and TcpListener
when you need to establish a reliable, connection-oriented communication channel between two applications. They are ideal for applications that require guaranteed delivery of data and where the order of the data is important.
Memory Footprint
The memory footprint of TcpClient
and TcpListener
depends on the amount of data being transmitted and buffered. Creating a large number of connections or buffering large amounts of data can increase memory usage. Use asynchronous operations and streaming to minimize memory consumption.
Alternatives
Alternatives to TcpClient
and TcpListener
include:
* **UDP (UdpClient
):** For connectionless communication where reliability is not critical.
* **HTTP (HttpClient
, HttpListener
):** For web-based communication using the HTTP protocol.
* **gRPC:** A modern, high-performance RPC framework.
* **SignalR:** For real-time web applications.
* **Named Pipes:** For inter-process communication on the same machine.
Pros
* Reliable, ordered data delivery. * Established connection for consistent communication. * Widely supported and well-understood protocol.
Cons
* Overhead of connection establishment and maintenance. * Can be slower than UDP due to error checking and retransmission. * More complex to implement than UDP.
FAQ
-
What's the difference between
TcpClient
andTcpListener
?
TcpListener
is used on the server side to listen for incoming connection requests on a specified port.TcpClient
is used on both the client and server side to establish a TCP connection. -
How do I handle multiple clients with
TcpListener
?
Use asynchronous methods (e.g.,AcceptTcpClientAsync
) and create a new thread or task to handle each client connection. This prevents blocking the main thread and allows the server to handle multiple clients concurrently. -
How do I ensure data is transmitted securely over TCP?
Use SSL/TLS encryption by wrapping theNetworkStream
with aSslStream
. This will encrypt the data being transmitted, protecting it from eavesdropping.