Elysia Tools
Navigation
C#
Windows Networking - C# Samples
Comprehensive C# networking examples for Windows platform including HTTP requests, TCP sockets, UDP communication, and web server implementation
Samples
Entries inside this sample collection
HTTP Requests with HttpClient
Making GET, POST, PUT, DELETE HTTP requests with C# HttpClient including error handling and async operations
Difficulty
4/10
Estimated time
25 min
Tags
csharp, http, networking, async, rest api, windows
Prerequisites
C# async/await, HTTP protocol basics, JSON serialization
using System;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
using System.Text;
using System.Text.Json;
class HttpRequestsDemo
{
private static readonly HttpClient httpClient = new HttpClient();
// 1. Simple GET request
public static async Task SimpleGetRequest()
{
Console.WriteLine("=== Simple GET Request ===");
try
{
// Set base address
httpClient.BaseAddress = new Uri("https://jsonplaceholder.typicode.com");
Console.WriteLine("Making GET request to /posts/1...");
HttpResponseMessage response = await httpClient.GetAsync("/posts/1");
if (response.IsSuccessStatusCode)
{
string content = await response.Content.ReadAsStringAsync();
Console.WriteLine($"Response Status: {response.StatusCode}");
Console.WriteLine($"Response Content: {content}");
}
else
{
Console.WriteLine($"Request failed with status: {response.StatusCode}");
}
}
catch (HttpRequestException ex)
{
Console.WriteLine($"HTTP Request Error: {ex.Message}");
}
catch (TaskCanceledException)
{
Console.WriteLine("Request timed out");
}
}
// 2. GET request with query parameters
public static async Task GetWithQueryParameters()
{
Console.WriteLine("\n=== GET Request with Query Parameters ===");
try
{
string userId = "1";
string url = $"/posts?userId={userId}&_limit=5";
Console.WriteLine($"Making GET request to: {url}");
HttpResponseMessage response = await httpClient.GetAsync(url);
if (response.IsSuccessStatusCode)
{
string content = await response.Content.ReadAsStringAsync();
Console.WriteLine($"Response Status: {response.StatusCode}");
Console.WriteLine($"Response Content: {content}");
}
}
catch (Exception ex)
{
Console.WriteLine($"Error: {ex.Message}");
}
}
// 3. POST request with JSON body
public static async Task PostRequestWithJson()
{
Console.WriteLine("\n=== POST Request with JSON Body ===");
try
{
var postData = new
{
title = "My New Post",
body = "This is the content of my new post",
userId = 1
};
string jsonContent = JsonSerializer.Serialize(postData);
var content = new StringContent(jsonContent, Encoding.UTF8, "application/json");
Console.WriteLine("Sending POST request to /posts...");
Console.WriteLine($"Request Body: {jsonContent}");
HttpResponseMessage response = await httpClient.PostAsync("/posts", content);
if (response.IsSuccessStatusCode)
{
string responseContent = await response.Content.ReadAsStringAsync();
Console.WriteLine($"Response Status: {response.StatusCode}");
Console.WriteLine($"Response Content: {responseContent}");
}
}
catch (Exception ex)
{
Console.WriteLine($"Error: {ex.Message}");
}
}
// 4. PUT request to update resource
public static async Task PutRequestToUpdate()
{
Console.WriteLine("\n=== PUT Request to Update Resource ===");
try
{
var updateData = new
{
id = 1,
title = "Updated Post Title",
body = "This post has been updated",
userId = 1
};
string jsonContent = JsonSerializer.Serialize(updateData);
var content = new StringContent(jsonContent, Encoding.UTF8, "application/json");
Console.WriteLine("Sending PUT request to /posts/1...");
Console.WriteLine($"Request Body: {jsonContent}");
HttpResponseMessage response = await httpClient.PutAsync("/posts/1", content);
if (response.IsSuccessStatusCode)
{
string responseContent = await response.Content.ReadAsStringAsync();
Console.WriteLine($"Response Status: {response.StatusCode}");
Console.WriteLine($"Response Content: {responseContent}");
}
}
catch (Exception ex)
{
Console.WriteLine($"Error: {ex.Message}");
}
}
// 5. DELETE request
public static async Task DeleteRequest()
{
Console.WriteLine("\n=== DELETE Request ===");
try
{
Console.WriteLine("Sending DELETE request to /posts/1...");
HttpResponseMessage response = await httpClient.DeleteAsync("/posts/1");
if (response.IsSuccessStatusCode)
{
string responseContent = await response.Content.ReadAsStringAsync();
Console.WriteLine($"Response Status: {response.StatusCode}");
Console.WriteLine($"Response Content: {responseContent}");
}
}
catch (Exception ex)
{
Console.WriteLine($"Error: {ex.Message}");
}
}
// 6. Request with custom headers
public static async Task RequestWithCustomHeaders()
{
Console.WriteLine("\n=== Request with Custom Headers ===");
try
{
// Clear existing headers
httpClient.DefaultRequestHeaders.Clear();
// Add custom headers
httpClient.DefaultRequestHeaders.Add("User-Agent", "MyCSharpApp/1.0");
httpClient.DefaultRequestHeaders.Add("Accept", "application/json");
httpClient.DefaultRequestHeaders.Add("X-Custom-Header", "CustomValue");
Console.WriteLine("Headers added to request");
HttpResponseMessage response = await httpClient.GetAsync("/posts/1");
if (response.IsSuccessStatusCode)
{
// Display response headers
Console.WriteLine("\nResponse Headers:");
foreach (var header in response.Headers)
{
Console.WriteLine($"{header.Key}: {string.Join(", ", header.Value)}");
}
string content = await response.Content.ReadAsStringAsync();
Console.WriteLine($"\nResponse Content: {content}");
}
}
catch (Exception ex)
{
Console.WriteLine($"Error: {ex.Message}");
}
}
// 7. Request with timeout
public static async Task RequestWithTimeout()
{
Console.WriteLine("\n=== Request with Timeout ===");
try
{
// Set timeout to 2 seconds
httpClient.Timeout = TimeSpan.FromSeconds(2);
Console.WriteLine("Making request with 2-second timeout...");
// This might timeout if the server is slow
HttpResponseMessage response = await httpClient.GetAsync("https://httpbin.org/delay/5");
if (response.IsSuccessStatusCode)
{
string content = await response.Content.ReadAsStringAsync();
Console.WriteLine($"Request completed: {content}");
}
}
catch (TaskCanceledException)
{
Console.WriteLine("Request timed out after 2 seconds");
}
catch (Exception ex)
{
Console.WriteLine($"Error: {ex.Message}");
}
finally
{
// Reset timeout
httpClient.Timeout = TimeSpan.FromSeconds(30);
}
}
// 8. Download file
public static async Task DownloadFile()
{
Console.WriteLine("\n=== Download File ===");
try
{
string fileUrl = "https://jsonplaceholder.typicode.com/posts/1";
string localFilePath = "downloaded_post.json";
Console.WriteLine($"Downloading file from: {fileUrl}");
HttpResponseMessage response = await httpClient.GetAsync(fileUrl);
response.EnsureSuccessStatusCode();
// Save to file
byte[] fileBytes = await response.Content.ReadAsByteArrayAsync();
await System.IO.File.WriteAllBytesAsync(localFilePath, fileBytes);
Console.WriteLine($"File downloaded successfully to: {localFilePath}");
Console.WriteLine($"File size: {fileBytes.Length} bytes");
// Display file content
string content = await System.IO.File.ReadAllTextAsync(localFilePath);
Console.WriteLine($"\nFile content: {content}");
// Cleanup
if (System.IO.File.Exists(localFilePath))
{
System.IO.File.Delete(localFilePath);
Console.WriteLine($"Cleaned up: {localFilePath}");
}
}
catch (Exception ex)
{
Console.WriteLine($"Error downloading file: {ex.Message}");
}
}
// 9. Upload file with multipart/form-data
public static async Task UploadFile()
{
Console.WriteLine("\n=== Upload File with Multipart Form Data ===");
try
{
// Create a temporary file to upload
string tempFilePath = "upload_test.txt";
await System.IO.File.WriteAllTextAsync(tempFilePath, "This is a test file for upload\nSecond line\nThird line");
using (var form = new MultipartFormDataContent())
{
// Add file
var fileContent = new ByteArrayContent(await System.IO.File.ReadAllBytesAsync(tempFilePath));
fileContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("text/plain");
form.Add(fileContent, "file", "test_upload.txt");
// Add form fields
form.Add(new StringContent("Document"), "documentType");
form.Add(new StringContent("Description of uploaded file"), "description");
Console.WriteLine("Uploading file with form data...");
// Note: This endpoint may not actually accept file uploads
// In real scenario, use proper file upload endpoint
HttpResponseMessage response = await httpClient.PostAsync("https://httpbin.org/post", form);
if (response.IsSuccessStatusCode)
{
string responseContent = await response.Content.ReadAsStringAsync();
Console.WriteLine($"Upload response: {responseContent}");
}
}
// Cleanup
if (System.IO.File.Exists(tempFilePath))
{
System.IO.File.Delete(tempFilePath);
}
}
catch (Exception ex)
{
Console.WriteLine($"Error uploading file: {ex.Message}");
}
}
// 10. Parallel requests
public static async Task ParallelRequests()
{
Console.WriteLine("\n=== Parallel HTTP Requests ===");
try
{
string[] endpoints = { "/posts/1", "/posts/2", "/posts/3", "/posts/4", "/posts/5" };
Console.WriteLine("Making 5 parallel requests...");
var stopwatch = System.Diagnostics.Stopwatch.StartNew();
// Create tasks for parallel requests
var tasks = endpoints.Select(async endpoint =>
{
try
{
var response = await httpClient.GetAsync(endpoint);
return new { Endpoint = endpoint, Status = response.StatusCode, Success = response.IsSuccessStatusCode };
}
catch (Exception ex)
{
return new { Endpoint = endpoint, Status = System.Net.HttpStatusCode.ServiceUnavailable, Success = false, Error = ex.Message };
}
});
// Wait for all requests to complete
var results = await Task.WhenAll(tasks);
stopwatch.Stop();
Console.WriteLine($"All {results.Length} requests completed in {stopwatch.ElapsedMilliseconds}ms");
foreach (var result in results)
{
if (result.Success)
{
Console.WriteLine($"✓ {result.Endpoint}: {result.Status}");
}
else
{
Console.WriteLine($"✗ {result.Endpoint}: {result.Status} {result.Error}");
}
}
}
catch (Exception ex)
{
Console.WriteLine($"Error in parallel requests: {ex.Message}");
}
}
// 11. Advanced error handling and retry logic
public static async Task RequestWithRetry()
{
Console.WriteLine("\n=== Request with Retry Logic ===");
int maxRetries = 3;
int delayMs = 1000;
for (int attempt = 1; attempt <= maxRetries; attempt++)
{
try
{
Console.WriteLine($"Attempt {attempt} of {maxRetries}");
// Use a URL that might fail sometimes
HttpResponseMessage response = await httpClient.GetAsync("https://httpbin.org/status/200,500");
if (response.IsSuccessStatusCode)
{
Console.WriteLine($"✓ Request succeeded on attempt {attempt}");
return;
}
else if ((int)response.StatusCode >= 500)
{
Console.WriteLine($"Server error: {response.StatusCode}, retrying...");
if (attempt < maxRetries)
{
await Task.Delay(delayMs * attempt); // Exponential backoff
}
}
else
{
Console.WriteLine($"Client error: {response.StatusCode}, not retrying");
return;
}
}
catch (HttpRequestException ex)
{
Console.WriteLine($"Network error on attempt {attempt}: {ex.Message}");
if (attempt < maxRetries)
{
await Task.Delay(delayMs * attempt);
}
}
}
Console.WriteLine("All retry attempts failed");
}
// 12. HTTP response streaming
public static async Task StreamResponse()
{
Console.WriteLine("\n=== HTTP Response Streaming ===");
try
{
HttpResponseMessage response = await httpClient.GetAsync("https://jsonplaceholder.typicode.com/posts", HttpCompletionOption.ResponseHeadersRead);
using (var stream = await response.Content.ReadAsStreamAsync())
using (var reader = new System.IO.StreamReader(stream))
{
char[] buffer = new char[1024];
int bytesRead;
int totalChars = 0;
Console.WriteLine("Streaming response content...");
while ((bytesRead = await reader.ReadAsync(buffer, 0, buffer.Length)) > 0)
{
totalChars += bytesRead;
string chunk = new string(buffer, 0, bytesRead);
Console.Write(chunk);
// Break after reading some content for demo
if (totalChars > 1000)
{
Console.WriteLine("\n... (streaming continues)");
break;
}
}
Console.WriteLine($"\n\nTotal characters read: {totalChars}");
}
}
catch (Exception ex)
{
Console.WriteLine($"Error streaming response: {ex.Message}");
}
}
// 13. HTTP client with proxy
public static async Task RequestWithProxy()
{
Console.WriteLine("\n=== HTTP Request with Proxy ===");
try
{
// Note: This is example code - proxy details would be different in real scenario
var proxy = new System.Net.WebProxy("http://proxy.example.com:8080")
{
BypassProxyOnLocal = false
};
// Create new HttpClient with proxy
var httpClientWithProxy = new HttpClient(new HttpClientHandler
{
Proxy = proxy,
UseProxy = true
});
Console.WriteLine("Making request through proxy...");
// This would be replaced with actual request in real scenario
Console.WriteLine("Proxy configuration complete (demo - not actually making request)");
httpClientWithProxy.Dispose();
}
catch (Exception ex)
{
Console.WriteLine($"Error with proxy: {ex.Message}");
}
}
static async Task Main(string[] args)
{
Console.WriteLine("=== C# HTTP Requests Demo ===\n");
try
{
await SimpleGetRequest();
await GetWithQueryParameters();
await PostRequestWithJson();
await PutRequestToUpdate();
await DeleteRequest();
await RequestWithCustomHeaders();
await RequestWithTimeout();
await DownloadFile();
await UploadFile();
await ParallelRequests();
await RequestWithRetry();
await StreamResponse();
await RequestWithProxy();
Console.WriteLine("\nAll HTTP request examples completed successfully!");
}
catch (Exception ex)
{
Console.WriteLine($"Error in HTTP demo: {ex.Message}");
}
finally
{
httpClient?.Dispose();
}
}
}TCP Socket Programming
Creating TCP clients and servers for bidirectional communication using C# sockets
Difficulty
6/10
Estimated time
30 min
Tags
csharp, tcp, socket, networking, server, client, windows
Prerequisites
C# async/await, Network programming basics, TCP/IP understanding
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Collections.Concurrent;
class TcpSocketDemo
{
// 1. Simple TCP Server
public static async Task SimpleTcpServer()
{
Console.WriteLine("=== Simple TCP Server ===");
int port = 8080;
TcpListener server = null;
try
{
server = new TcpListener(IPAddress.Any, port);
server.Start();
Console.WriteLine($"TCP Server started on port {port}");
Console.WriteLine("Waiting for client connections...");
while (true)
{
TcpClient client = await server.AcceptTcpClientAsync();
Console.WriteLine($"Client connected from {client.Client.RemoteEndPoint}");
// Handle client in a separate task
_ = Task.Run(() => HandleSimpleClient(client));
}
}
catch (Exception ex)
{
Console.WriteLine($"Server error: {ex.Message}");
}
finally
{
server?.Stop();
}
}
static async Task HandleSimpleClient(TcpClient client)
{
try
{
using (client)
using (NetworkStream stream = client.GetStream())
{
byte[] buffer = new byte[1024];
StringBuilder message = new StringBuilder();
while (true)
{
int bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length);
if (bytesRead == 0) break; // Client disconnected
string data = Encoding.UTF8.GetString(buffer, 0, bytesRead);
message.Append(data);
if (data.Contains("\n"))
{
string fullMessage = message.ToString().Trim();
Console.WriteLine($"Received: {fullMessage}");
// Echo back response
string response = $"Server received: {fullMessage}\n";
byte[] responseBytes = Encoding.UTF8.GetBytes(response);
await stream.WriteAsync(responseBytes, 0, responseBytes.Length);
message.Clear();
}
}
}
}
catch (Exception ex)
{
Console.WriteLine($"Error handling client: {ex.Message}");
}
finally
{
Console.WriteLine($"Client disconnected");
}
}
// 2. Simple TCP Client
public static async Task SimpleTcpClient(string serverIp = "127.0.0.1", int port = 8080)
{
Console.WriteLine("\n=== Simple TCP Client ===");
try
{
using (TcpClient client = new TcpClient())
{
Console.WriteLine($"Connecting to server {serverIp}:{port}...");
await client.ConnectAsync(serverIp, port);
Console.WriteLine("Connected to server!");
using (NetworkStream stream = client.GetStream())
{
// Send messages
string[] messages = {
"Hello, Server!",
"This is message 2",
"Final message from client"
};
foreach (string message in messages)
{
Console.WriteLine($"Sending: {message}");
byte[] messageBytes = Encoding.UTF8.GetBytes(message + "\n");
await stream.WriteAsync(messageBytes, 0, messageBytes.Length);
// Receive response
byte[] buffer = new byte[1024];
int bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length);
string response = Encoding.UTF8.GetString(buffer, 0, bytesRead).Trim();
Console.WriteLine($"Received: {response}");
await Task.Delay(1000);
}
}
Console.WriteLine("Communication completed");
}
}
catch (Exception ex)
{
Console.WriteLine($"Client error: {ex.Message}");
}
}
// 3. TCP Server with Multiple Client Support
public static async Task MultiClientTcpServer()
{
Console.WriteLine("\n=== Multi-Client TCP Server ===");
int port = 8081;
TcpListener server = null;
ConcurrentDictionary<string, TcpClient> clients = new ConcurrentDictionary<string, TcpClient>();
try
{
server = new TcpListener(IPAddress.Any, port);
server.Start();
Console.WriteLine($"Multi-client server started on port {port}");
// Accept clients continuously
while (true)
{
TcpClient client = await server.AcceptTcpClientAsync();
string clientId = $"Client_{DateTime.Now:HHmmss}_{client.Client.RemoteEndPoint}";
clients[clientId] = client;
Console.WriteLine($"New client connected: {clientId}");
_ = Task.Run(() => HandleMultiClient(client, clientId, clients));
}
}
catch (Exception ex)
{
Console.WriteLine($"Server error: {ex.Message}");
}
finally
{
server?.Stop();
}
}
static async Task HandleMultiClient(TcpClient client, string clientId, ConcurrentDictionary<string, TcpClient> clients)
{
try
{
using (client)
using (NetworkStream stream = client.GetStream())
{
// Send welcome message
string welcome = $"Welcome! You are {clientId}. Connected clients: {clients.Count}\n";
byte[] welcomeBytes = Encoding.UTF8.GetBytes(welcome);
await stream.WriteAsync(welcomeBytes, 0, welcomeBytes.Length);
while (true)
{
byte[] buffer = new byte[1024];
int bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length);
if (bytesRead == 0) break;
string message = Encoding.UTF8.GetString(buffer, 0, bytesRead).Trim();
Console.WriteLine($"{clientId}: {message}");
// Broadcast message to all clients (except sender)
string broadcastMsg = $"{clientId}: {message}\n";
byte[] broadcastBytes = Encoding.UTF8.GetBytes(broadcastMsg);
foreach (var kvp in clients)
{
try
{
if (kvp.Key != clientId && kvp.Value.Connected)
{
NetworkStream clientStream = kvp.Value.GetStream();
await clientStream.WriteAsync(broadcastBytes, 0, broadcastBytes.Length);
}
}
catch
{
// Remove disconnected client
clients.TryRemove(kvp.Key, out _);
}
}
}
}
}
catch (Exception ex)
{
Console.WriteLine($"Error handling client {clientId}: {ex.Message}");
}
finally
{
clients.TryRemove(clientId, out _);
Console.WriteLine($"{clientId} disconnected");
}
}
// 4. TCP File Transfer Server
public static async Task FileTransferServer()
{
Console.WriteLine("\n=== TCP File Transfer Server ===");
int port = 8082;
TcpListener server = null;
try
{
server = new TcpListener(IPAddress.Any, port);
server.Start();
Console.WriteLine($"File transfer server started on port {port}");
while (true)
{
TcpClient client = await server.AcceptTcpClientAsync();
Console.WriteLine($"File client connected from {client.Client.RemoteEndPoint}");
_ = Task.Run(() => HandleFileTransferClient(client));
}
}
catch (Exception ex)
{
Console.WriteLine($"File server error: {ex.Message}");
}
finally
{
server?.Stop();
}
}
static async Task HandleFileTransferClient(TcpClient client)
{
try
{
using (client)
using (NetworkStream stream = client.GetStream())
{
// Receive filename
byte[] fileNameBuffer = new byte[256];
int fileNameBytes = await stream.ReadAsync(fileNameBuffer, 0, fileNameBuffer.Length);
string fileName = Encoding.UTF8.GetString(fileNameBuffer, 0, fileNameBytes).Trim('\0');
Console.WriteLine($"Receiving file: {fileName}");
// Receive file size
byte[] fileSizeBuffer = new byte[8];
await stream.ReadAsync(fileSizeBuffer, 0, 8);
long fileSize = BitConverter.ToInt64(fileSizeBuffer, 0);
Console.WriteLine($"File size: {fileSize} bytes");
// Receive file content
using (var fileStream = System.IO.File.Create($"received_{fileName}"))
{
long totalBytesReceived = 0;
byte[] buffer = new byte[8192];
while (totalBytesReceived < fileSize)
{
int bytesToRead = (int)Math.Min(buffer.Length, fileSize - totalBytesReceived);
int bytesRead = await stream.ReadAsync(buffer, 0, bytesToRead);
if (bytesRead == 0) break;
await fileStream.WriteAsync(buffer, 0, bytesRead);
totalBytesReceived += bytesRead;
// Show progress
double progress = (double)totalBytesReceived / fileSize * 100;
Console.Write($"\rProgress: {progress:F1}% ({totalBytesReceived:N0}/{fileSize:N0} bytes)");
}
Console.WriteLine("\nFile received successfully!");
}
// Send confirmation
string confirmation = "File received successfully\n";
byte[] confirmationBytes = Encoding.UTF8.GetBytes(confirmation);
await stream.WriteAsync(confirmationBytes, 0, confirmationBytes.Length);
}
}
catch (Exception ex)
{
Console.WriteLine($"File transfer error: {ex.Message}");
}
}
// 5. TCP File Transfer Client
public static async Task FileTransferClient(string filePath, string serverIp = "127.0.0.1", int port = 8082)
{
Console.WriteLine("\n=== TCP File Transfer Client ===");
if (!System.IO.File.Exists(filePath))
{
Console.WriteLine($"File not found: {filePath}");
return;
}
try
{
using (TcpClient client = new TcpClient())
{
Console.WriteLine($"Connecting to file server {serverIp}:{port}...");
await client.ConnectAsync(serverIp, port);
Console.WriteLine("Connected to file server!");
using (NetworkStream stream = client.GetStream())
using (var fileStream = System.IO.File.OpenRead(filePath))
{
// Send filename
string fileName = System.IO.Path.GetFileName(filePath);
byte[] fileNameBytes = Encoding.UTF8.GetBytes(fileName);
await stream.WriteAsync(fileNameBytes, 0, fileNameBytes.Length);
Console.WriteLine($"Sending file: {fileName}");
// Send file size
long fileSize = fileStream.Length;
byte[] fileSizeBytes = BitConverter.GetBytes(fileSize);
await stream.WriteAsync(fileSizeBytes, 0, fileSizeBytes.Length);
Console.WriteLine($"File size: {fileSize:N0} bytes");
// Send file content
byte[] buffer = new byte[8192];
long totalBytesSent = 0;
while (totalBytesSent < fileSize)
{
int bytesRead = await fileStream.ReadAsync(buffer, 0, buffer.Length);
await stream.WriteAsync(buffer, 0, bytesRead);
totalBytesSent += bytesRead;
// Show progress
double progress = (double)totalBytesSent / fileSize * 100;
Console.Write($"\rProgress: {progress:F1}% ({totalBytesSent:N0}/{fileSize:N0} bytes)");
}
Console.WriteLine("\nFile sent successfully!");
// Receive confirmation
byte[] confirmationBuffer = new byte[1024];
int confirmationBytes = await stream.ReadAsync(confirmationBuffer, 0, confirmationBuffer.Length);
string confirmation = Encoding.UTF8.GetString(confirmationBuffer, 0, confirmationBytes).Trim();
Console.WriteLine($"Server confirmation: {confirmation}");
}
}
}
catch (Exception ex)
{
Console.WriteLine($"File transfer client error: {ex.Message}");
}
}
// 6. TCP Chat Server
public static async Task TcpChatServer()
{
Console.WriteLine("\n=== TCP Chat Server ===");
int port = 8083;
TcpListener server = null;
ConcurrentDictionary<string, TcpClient> chatClients = new ConcurrentDictionary<string, TcpClient>();
try
{
server = new TcpListener(IPAddress.Any, port);
server.Start();
Console.WriteLine($"Chat server started on port {port}");
// Accept clients
while (true)
{
TcpClient client = await server.AcceptTcpClientAsync();
string username = await GetUsername(client);
if (username != null)
{
chatClients[username] = client;
Console.WriteLine($"{username} joined the chat");
// Broadcast join message
await BroadcastMessage($"{username} joined the chat\n", chatClients, username);
_ = Task.Run(() => HandleChatClient(client, username, chatClients));
}
}
}
catch (Exception ex)
{
Console.WriteLine($"Chat server error: {ex.Message}");
}
finally
{
server?.Stop();
}
}
static async Task<string> GetUsername(TcpClient client)
{
try
{
using (NetworkStream stream = client.GetStream())
{
byte[] buffer = new byte[1024];
int bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length);
string username = Encoding.UTF8.GetString(buffer, 0, bytesRead).Trim();
return !string.IsNullOrEmpty(username) ? username : null;
}
}
catch
{
return null;
}
}
static async Task HandleChatClient(TcpClient client, string username, ConcurrentDictionary<string, TcpClient> clients)
{
try
{
using (client)
using (NetworkStream stream = client.GetStream())
{
while (true)
{
byte[] buffer = new byte[1024];
int bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length);
if (bytesRead == 0) break;
string message = Encoding.UTF8.GetString(buffer, 0, bytesRead).Trim();
Console.WriteLine($"{username}: {message}");
// Broadcast message to all clients
await BroadcastMessage($"{username}: {message}\n", clients);
}
}
}
catch (Exception ex)
{
Console.WriteLine($"Error handling {username}: {ex.Message}");
}
finally
{
clients.TryRemove(username, out _);
Console.WriteLine($"{username} left the chat");
// Broadcast leave message
_ = BroadcastMessage($"{username} left the chat\n", clients);
}
}
static async Task BroadcastMessage(string message, ConcurrentDictionary<string, TcpClient> clients, string excludeUser = null)
{
byte[] messageBytes = Encoding.UTF8.GetBytes(message);
foreach (var kvp in clients)
{
if (kvp.Key != excludeUser)
{
try
{
NetworkStream stream = kvp.Value.GetStream();
await stream.WriteAsync(messageBytes, 0, messageBytes.Length);
}
catch
{
// Remove disconnected client
clients.TryRemove(kvp.Key, out _);
}
}
}
}
// 7. TCP Chat Client
public static async Task TcpChatClient(string username, string serverIp = "127.0.0.1", int port = 8083)
{
Console.WriteLine("\n=== TCP Chat Client ===");
try
{
using (TcpClient client = new TcpClient())
{
Console.WriteLine($"Connecting to chat server {serverIp}:{port}...");
await client.ConnectAsync(serverIp, port);
Console.WriteLine("Connected to chat server!");
using (NetworkStream stream = client.GetStream())
{
// Send username
byte[] usernameBytes = Encoding.UTF8.GetBytes(username);
await stream.WriteAsync(usernameBytes, 0, usernameBytes.Length);
// Start receiving messages
_ = Task.Run(async () =>
{
byte[] buffer = new byte[1024];
while (true)
{
int bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length);
if (bytesRead == 0) break;
string message = Encoding.UTF8.GetString(buffer, 0, bytesRead);
Console.Write(message);
}
});
// Send messages from console
Console.WriteLine("\nType your messages (type 'quit' to exit):");
while (true)
{
string input = Console.ReadLine();
if (string.IsNullOrEmpty(input)) continue;
if (input.ToLower() == "quit")
{
break;
}
byte[] messageBytes = Encoding.UTF8.GetBytes(input);
await stream.WriteAsync(messageBytes, 0, messageBytes.Length);
}
}
}
}
catch (Exception ex)
{
Console.WriteLine($"Chat client error: {ex.Message}");
}
}
// 8. TCP Server with Protocol
public static async Task ProtocolTcpServer()
{
Console.WriteLine("\n=== TCP Server with Protocol ===");
int port = 8084;
TcpListener server = null;
try
{
server = new TcpListener(IPAddress.Any, port);
server.Start();
Console.WriteLine($"Protocol server started on port {port}");
while (true)
{
TcpClient client = await server.AcceptTcpClientAsync();
Console.WriteLine($"Protocol client connected from {client.Client.RemoteEndPoint}");
_ = Task.Run(() => HandleProtocolClient(client));
}
}
catch (Exception ex)
{
Console.WriteLine($"Protocol server error: {ex.Message}");
}
finally
{
server?.Stop();
}
}
static async Task HandleProtocolClient(TcpClient client)
{
try
{
using (client)
using (NetworkStream stream = client.GetStream())
{
while (true)
{
// Read message type (1 byte)
byte[] typeBuffer = new byte[1];
int typeBytesRead = await stream.ReadAsync(typeBuffer, 0, 1);
if (typeBytesRead == 0) break;
byte messageType = typeBuffer[0];
// Read message length (4 bytes)
byte[] lengthBuffer = new byte[4];
await stream.ReadAsync(lengthBuffer, 0, 4);
int messageLength = BitConverter.ToInt32(lengthBuffer, 0);
// Read message content
byte[] messageBuffer = new byte[messageLength];
await stream.ReadAsync(messageBuffer, 0, messageLength);
string messageContent = Encoding.UTF8.GetString(messageBuffer);
Console.WriteLine($"Received message type: {messageType}, length: {messageLength}, content: {messageContent}");
// Process and respond based on message type
string response = ProcessMessage(messageType, messageContent);
await SendProtocolMessage(stream, messageType, response);
}
}
}
catch (Exception ex)
{
Console.WriteLine($"Protocol client error: {ex.Message}");
}
}
static string ProcessMessage(byte messageType, string content)
{
switch (messageType)
{
case 1: // Echo
return $"Echo: {content}";
case 2: // Upper case
return content.ToUpper();
case 3: // Reverse
char[] chars = content.ToCharArray();
Array.Reverse(chars);
return new string(chars);
case 4: // Get time
return DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
default:
return "Unknown message type";
}
}
static async Task SendProtocolMessage(NetworkStream stream, byte messageType, string content)
{
byte[] messageBytes = Encoding.UTF8.GetBytes(content);
byte[] lengthBytes = BitConverter.GetBytes(messageBytes.Length);
await stream.WriteAsync(new byte[] { messageType }, 0, 1);
await stream.WriteAsync(lengthBytes, 0, 4);
await stream.WriteAsync(messageBytes, 0, messageBytes.Length);
}
// 9. TCP Protocol Client
public static async Task ProtocolTcpClient(string serverIp = "127.0.0.1", int port = 8084)
{
Console.WriteLine("\n=== TCP Protocol Client ===");
try
{
using (TcpClient client = new TcpClient())
{
Console.WriteLine($"Connecting to protocol server {serverIp}:{port}...");
await client.ConnectAsync(serverIp, port);
Console.WriteLine("Connected to protocol server!");
using (NetworkStream stream = client.GetStream())
{
// Test different message types
string[] testMessages = { "Hello World", "This will be uppercased", "Reverse this string" };
byte[] messageTypes = { 1, 2, 3 };
for (int i = 0; i < testMessages.Length; i++)
{
Console.WriteLine($"Sending message type {messageTypes[i]}: {testMessages[i]}");
await SendProtocolMessage(stream, messageTypes[i], testMessages[i]);
// Receive response
byte[] responseTypeBuffer = new byte[1];
await stream.ReadAsync(responseTypeBuffer, 0, 1);
byte[] responseLengthBuffer = new byte[4];
await stream.ReadAsync(responseLengthBuffer, 0, 4);
int responseLength = BitConverter.ToInt32(responseLengthBuffer, 0);
byte[] responseBuffer = new byte[responseLength];
await stream.ReadAsync(responseBuffer, 0, responseLength);
string response = Encoding.UTF8.GetString(responseBuffer);
Console.WriteLine($"Received response: {response}\n");
await Task.Delay(1000);
}
}
}
}
catch (Exception ex)
{
Console.WriteLine($"Protocol client error: {ex.Message}");
}
}
// 10. TCP Keep-alive and Heartbeat
public static async Task HeartbeatTcpServer()
{
Console.WriteLine("\n=== TCP Heartbeat Server ===");
int port = 8085;
TcpListener server = null;
try
{
server = new TcpListener(IPAddress.Any, port);
server.Start();
Console.WriteLine($"Heartbeat server started on port {port}");
while (true)
{
TcpClient client = await server.AcceptTcpClientAsync();
Console.WriteLine($"Heartbeat client connected from {client.Client.RemoteEndPoint}");
_ = Task.Run(() => HandleHeartbeatClient(client));
}
}
catch (Exception ex)
{
Console.WriteLine($"Heartbeat server error: {ex.Message}");
}
finally
{
server?.Stop();
}
}
static async Task HandleHeartbeatClient(TcpClient client)
{
DateTime lastHeartbeat = DateTime.Now;
int missedHeartbeats = 0;
const int maxMissedHeartbeats = 3;
try
{
using (client)
using (NetworkStream stream = client.GetStream())
{
// Send initial heartbeat request
await SendHeartbeat(stream);
while (true)
{
// Wait for heartbeat response (5 second timeout)
byte[] buffer = new byte[1024];
var readTask = stream.ReadAsync(buffer, 0, buffer.Length);
var timeoutTask = Task.Delay(5000);
var completedTask = await Task.WhenAny(readTask, timeoutTask);
if (completedTask == timeoutTask)
{
missedHeartbeats++;
Console.WriteLine($"Missed heartbeat {missedHeartbeats}/{maxMissedHeartbeats}");
if (missedHeartbeats >= maxMissedHeartbeats)
{
Console.WriteLine("Client disconnected - too many missed heartbeats");
break;
}
await SendHeartbeat(stream);
continue;
}
int bytesRead = await readTask;
if (bytesRead == 0) break;
string message = Encoding.UTF8.GetString(buffer, 0, bytesRead).Trim();
if (message == "HEARTBEAT")
{
lastHeartbeat = DateTime.Now;
missedHeartbeats = 0;
Console.WriteLine($"Received heartbeat from client");
await SendHeartbeatAck(stream);
}
}
}
}
catch (Exception ex)
{
Console.WriteLine($"Heartbeat client error: {ex.Message}");
}
}
static async Task SendHeartbeat(NetworkStream stream)
{
string message = "HEARTBEAT\n";
byte[] messageBytes = Encoding.UTF8.GetBytes(message);
await stream.WriteAsync(messageBytes, 0, messageBytes.Length);
}
static async Task SendHeartbeatAck(NetworkStream stream)
{
string message = "HEARTBEAT_ACK\n";
byte[] messageBytes = Encoding.UTF8.GetBytes(message);
await stream.WriteAsync(messageBytes, 0, messageBytes.Length);
}
// 11. TCP Heartbeat Client
public static async Task HeartbeatTcpClient(string serverIp = "127.0.0.1", int port = 8085)
{
Console.WriteLine("\n=== TCP Heartbeat Client ===");
try
{
using (TcpClient client = new TcpClient())
{
Console.WriteLine($"Connecting to heartbeat server {serverIp}:{port}...");
await client.ConnectAsync(serverIp, port);
Console.WriteLine("Connected to heartbeat server!");
using (NetworkStream stream = client.GetStream())
{
// Handle server messages
_ = Task.Run(async () =>
{
byte[] buffer = new byte[1024];
while (true)
{
int bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length);
if (bytesRead == 0) break;
string message = Encoding.UTF8.GetString(buffer, 0, bytesRead).Trim();
if (message == "HEARTBEAT")
{
Console.WriteLine("Received heartbeat request");
string response = "HEARTBEAT\n";
byte[] responseBytes = Encoding.UTF8.GetBytes(response);
await stream.WriteAsync(responseBytes, 0, responseBytes.Length);
Console.WriteLine("Sent heartbeat response");
}
else if (message == "HEARTBEAT_ACK")
{
Console.WriteLine("Received heartbeat acknowledgment");
}
}
});
// Keep client alive
Console.WriteLine("Heartbeat client running. Press Enter to stop...");
Console.ReadLine();
}
}
}
catch (Exception ex)
{
Console.WriteLine($"Heartbeat client error: {ex.Message}");
}
}
static async Task Main(string[] args)
{
Console.WriteLine("=== C# TCP Socket Demo ===\n");
try
{
Console.WriteLine("Choose which demo to run:");
Console.WriteLine("1. Simple TCP Server");
Console.WriteLine("2. Simple TCP Client");
Console.WriteLine("3. File Transfer");
Console.WriteLine("4. Chat Server");
Console.WriteLine("5. Protocol Server");
// Note: In real scenario, you would choose one demo at a time
Console.WriteLine("\nNote: Each demo runs continuously. Start appropriate client/server pairs.");
// Example: Run file transfer
Console.WriteLine("\nStarting File Transfer Server on port 8082...");
_ = Task.Run(() => FileTransferServer());
// Wait a bit then start client with test file
await Task.Delay(2000);
// Create a test file
string testFile = "test_transfer.txt";
await System.IO.File.WriteAllTextAsync(testFile, "This is a test file for TCP transfer\nLine 2\nLine 3");
Console.WriteLine($"Starting file transfer client for {testFile}...");
await FileTransferClient(testFile);
// Cleanup
if (System.IO.File.Exists(testFile))
{
System.IO.File.Delete(testFile);
}
if (System.IO.File.Exists("received_test_transfer.txt"))
{
System.IO.File.Delete("received_test_transfer.txt");
}
Console.WriteLine("\nTCP socket demos completed!");
}
catch (Exception ex)
{
Console.WriteLine($"Error in TCP demo: {ex.Message}");
}
}
}UDP Socket Programming
UDP client and server implementation for connectionless communication, broadcasting, and multicast
Difficulty
6/10
Estimated time
28 min
Tags
csharp, udp, socket, networking, broadcast, multicast, windows
Prerequisites
C# async/await, Network programming basics, UDP understanding
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
class UdpSocketDemo
{
// 1. Simple UDP Server
public static async Task SimpleUdpServer()
{
Console.WriteLine("=== Simple UDP Server ===");
int port = 9090;
UdpClient udpServer = null;
try
{
udpServer = new UdpClient(port);
Console.WriteLine($"UDP Server started on port {port}");
Console.WriteLine("Waiting for UDP messages...");
while (true)
{
var result = await udpServer.ReceiveAsync();
string receivedMessage = Encoding.UTF8.GetString(result.Buffer);
IPEndPoint clientEndPoint = result.RemoteEndPoint;
Console.WriteLine($"Received from {clientEndPoint}: {receivedMessage}");
// Echo back response
string response = $"Server received: {receivedMessage}";
byte[] responseBytes = Encoding.UTF8.GetBytes(response);
await udpServer.SendAsync(responseBytes, responseBytes.Length, clientEndPoint);
}
}
catch (Exception ex)
{
Console.WriteLine($"UDP Server error: {ex.Message}");
}
finally
{
udpServer?.Close();
}
}
// 2. Simple UDP Client
public static async Task SimpleUdpClient(string serverIp = "127.0.0.1", int port = 9090)
{
Console.WriteLine("\n=== Simple UDP Client ===");
UdpClient udpClient = null;
try
{
udpClient = new UdpClient();
IPEndPoint serverEndPoint = new IPEndPoint(IPAddress.Parse(serverIp), port);
string[] messages = {
"Hello, UDP Server!",
"This is message 2",
"Final message from UDP client"
};
foreach (string message in messages)
{
Console.WriteLine($"Sending: {message}");
byte[] messageBytes = Encoding.UTF8.GetBytes(message);
await udpClient.SendAsync(messageBytes, messageBytes.Length, serverEndPoint);
// Receive response
var response = await udpClient.ReceiveAsync();
string responseMessage = Encoding.UTF8.GetString(response.Buffer);
Console.WriteLine($"Received from server: {responseMessage}");
await Task.Delay(1000);
}
}
catch (Exception ex)
{
Console.WriteLine($"UDP Client error: {ex.Message}");
}
finally
{
udpClient?.Close();
}
}
// 3. UDP Broadcast Server
public static async Task UdpBroadcastServer()
{
Console.WriteLine("\n=== UDP Broadcast Server ===");
int port = 9091;
UdpClient udpServer = null;
try
{
udpServer = new UdpClient();
udpServer.EnableBroadcast = true;
udpServer.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
udpServer.Client.Bind(new IPEndPoint(IPAddress.Any, port));
Console.WriteLine($"UDP Broadcast Server started on port {port}");
Console.WriteLine("Waiting for broadcast messages...");
while (true)
{
var result = await udpServer.ReceiveAsync();
string receivedMessage = Encoding.UTF8.GetString(result.Buffer);
IPEndPoint clientEndPoint = result.RemoteEndPoint;
Console.WriteLine($"Broadcast received from {clientEndPoint}: {receivedMessage}");
// Respond to the sender
string response = $"Server received broadcast: {receivedMessage}";
byte[] responseBytes = Encoding.UTF8.GetBytes(response);
await udpServer.SendAsync(responseBytes, responseBytes.Length, clientEndPoint);
}
}
catch (Exception ex)
{
Console.WriteLine($"Broadcast Server error: {ex.Message}");
}
finally
{
udpServer?.Close();
}
}
// 4. UDP Broadcast Client
public static async Task UdpBroadcastClient(int port = 9091)
{
Console.WriteLine("\n=== UDP Broadcast Client ===");
UdpClient udpClient = null;
try
{
udpClient = new UdpClient();
udpClient.EnableBroadcast = true;
// Get broadcast address (typically last address in subnet)
IPAddress broadcastAddress = IPAddress.Broadcast;
IPEndPoint broadcastEndPoint = new IPEndPoint(broadcastAddress, port);
Console.WriteLine($"Sending broadcasts to {broadcastAddress}:{port}");
string[] messages = {
"Broadcast Message 1",
"Broadcast Message 2",
"Anyone out there?"
};
foreach (string message in messages)
{
Console.WriteLine($"Broadcasting: {message}");
byte[] messageBytes = Encoding.UTF8.GetBytes(message);
await udpClient.SendAsync(messageBytes, messageBytes.Length, broadcastEndPoint);
// Wait for responses
var receiveTask = udpClient.ReceiveAsync();
var timeoutTask = Task.Delay(3000);
var completedTask = await Task.WhenAny(receiveTask, timeoutTask);
if (completedTask == receiveTask)
{
var response = await receiveTask;
string responseMessage = Encoding.UTF8.GetString(response.Buffer);
Console.WriteLine($"Response from {response.RemoteEndPoint}: {responseMessage}");
}
else
{
Console.WriteLine("No response received within timeout");
}
await Task.Delay(1000);
}
}
catch (Exception ex)
{
Console.WriteLine($"Broadcast Client error: {ex.Message}");
}
finally
{
udpClient?.Close();
}
}
// 5. UDP Multicast Server
public static async Task UdpMulticastServer()
{
Console.WriteLine("\n=== UDP Multicast Server ===");
string multicastAddress = "239.0.0.1";
int port = 9092;
UdpClient udpClient = null;
try
{
// Create and bind UDP client
udpClient = new UdpClient();
udpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
udpClient.Client.Bind(new IPEndPoint(IPAddress.Any, port));
// Join multicast group
udpClient.JoinMulticastGroup(IPAddress.Parse(multicastAddress));
Console.WriteLine($"UDP Multicast Server joined group {multicastAddress}:{port}");
while (true)
{
var result = await udpClient.ReceiveAsync();
string receivedMessage = Encoding.UTF8.GetString(result.Buffer);
IPEndPoint senderEndPoint = result.RemoteEndPoint;
Console.WriteLine($"Multicast message from {senderEndPoint}: {receivedMessage}");
}
}
catch (Exception ex)
{
Console.WriteLine($"Multicast Server error: {ex.Message}");
}
finally
{
udpClient?.DropMulticastGroup(IPAddress.Parse(multicastAddress));
udpClient?.Close();
}
}
// 6. UDP Multicast Client
public static async Task UdpMulticastClient()
{
Console.WriteLine("\n=== UDP Multicast Client ===");
string multicastAddress = "239.0.0.1";
int port = 9092;
UdpClient udpClient = null;
try
{
udpClient = new UdpClient();
IPEndPoint multicastEndPoint = new IPEndPoint(IPAddress.Parse(multicastAddress), port);
string[] messages = {
"Multicast Message 1",
"Hello multicast group!",
"Final multicast message"
};
foreach (string message in messages)
{
Console.WriteLine($"Sending multicast: {message}");
byte[] messageBytes = Encoding.UTF8.GetBytes(message);
await udpClient.SendAsync(messageBytes, messageBytes.Length, multicastEndPoint);
await Task.Delay(2000);
}
}
catch (Exception ex)
{
Console.WriteLine($"Multicast Client error: {ex.Message}");
}
finally
{
udpClient?.Close();
}
}
// 7. UDP File Transfer (with acknowledgment)
public static async Task UdpFileServer()
{
Console.WriteLine("\n=== UDP File Server ===");
int port = 9093;
UdpClient udpClient = null;
try
{
udpClient = new UdpClient(port);
Console.WriteLine($"UDP File Server listening on port {port}");
while (true)
{
var result = await udpClient.ReceiveAsync();
ProcessFileTransferRequest(udpClient, result.Buffer, result.RemoteEndPoint);
}
}
catch (Exception ex)
{
Console.WriteLine($"UDP File Server error: {ex.Message}");
}
finally
{
udpClient?.Close();
}
}
static async Task ProcessFileTransferRequest(UdpClient udpClient, byte[] data, IPEndPoint clientEndPoint)
{
try
{
string request = Encoding.UTF8.GetString(data);
string[] parts = request.Split(':');
if (parts.Length == 2 && parts[0] == "REQUEST_FILE")
{
string fileName = parts[1];
Console.WriteLine($"File request received: {fileName}");
if (System.IO.File.Exists(fileName))
{
byte[] fileData = await System.IO.File.ReadAllBytesAsync(fileName);
const int chunkSize = 1024; // Small chunks for UDP
Console.WriteLine($"Sending file {fileName} ({fileData.Length} bytes) in chunks of {chunkSize}");
for (int i = 0; i < fileData.Length; i += chunkSize)
{
int chunkLength = Math.Min(chunkSize, fileData.Length - i);
byte[] chunk = new byte[chunkLength + 8]; // 8 bytes for sequence number
// Add sequence number
BitConverter.GetBytes(i).CopyTo(chunk, 0);
// Add data
Array.Copy(fileData, i, chunk, 8, chunkLength);
await udpClient.SendAsync(chunk, chunk.Length, clientEndPoint);
// Wait for acknowledgment
var ackResult = await udpClient.ReceiveAsync();
string ack = Encoding.UTF8.GetString(ackResult.Buffer);
if (ack != $"ACK:{i}")
{
Console.WriteLine($"Missing ACK for chunk at position {i}, resending...");
await udpClient.SendAsync(chunk, chunk.Length, clientEndPoint);
}
Console.Write($"\rProgress: {Math.Min(100, (i + chunkLength) * 100 / fileData.Length)}%");
await Task.Delay(10); // Small delay
}
// Send end marker
byte[] endMarker = Encoding.UTF8.GetBytes("END:FILE");
await udpClient.SendAsync(endMarker, endMarker.Length, clientEndPoint);
Console.WriteLine("\nFile transfer completed");
}
else
{
string error = "ERROR:File not found";
byte[] errorBytes = Encoding.UTF8.GetBytes(error);
await udpClient.SendAsync(errorBytes, errorBytes.Length, clientEndPoint);
}
}
}
catch (Exception ex)
{
Console.WriteLine($"Error processing file transfer: {ex.Message}");
}
}
// 8. UDP File Client
public static async Task UdpFileClient(string fileName, string serverIp = "127.0.0.1", int port = 9093)
{
Console.WriteLine("\n=== UDP File Client ===");
UdpClient udpClient = null;
try
{
udpClient = new UdpClient();
IPEndPoint serverEndPoint = new IPEndPoint(IPAddress.Parse(serverIp), port);
// Request file
string request = $"REQUEST_FILE:{fileName}";
byte[] requestBytes = Encoding.UTF8.GetBytes(request);
await udpClient.SendAsync(requestBytes, requestBytes.Length, serverEndPoint);
Console.WriteLine($"Requested file: {fileName}");
// Receive file data
var fileData = new System.Collections.Generic.List<byte>();
var receivedChunks = new System.Collections.Generic.SortedDictionary<int, byte[]>();
while (true)
{
var result = await udpClient.ReceiveAsync();
byte[] data = result.Buffer;
if (data.Length >= 8)
{
string header = Encoding.UTF8.GetString(data, 0, 4);
if (header == "END:")
{
Console.WriteLine("\nFile transfer completed");
break;
}
else if (header.StartsWith("ERROR:"))
{
Console.WriteLine($"\nServer error: {Encoding.UTF8.GetString(data)}");
return;
}
else
{
// File data chunk
int sequenceNumber = BitConverter.ToInt32(data, 0);
byte[] chunkData = new byte[data.Length - 8];
Array.Copy(data, 8, chunkData, 0, chunkData.Length);
receivedChunks[sequenceNumber] = chunkData;
// Send acknowledgment
string ack = $"ACK:{sequenceNumber}";
byte[] ackBytes = Encoding.UTF8.GetBytes(ack);
await udpClient.SendAsync(ackBytes, ackBytes.Length, serverEndPoint);
Console.Write($"\rReceived {receivedChunks.Count} chunks");
}
}
}
// Assemble file
using (var fileStream = System.IO.File.Create($"received_{fileName}"))
{
foreach (var chunk in receivedChunks.Values)
{
await fileStream.WriteAsync(chunk, 0, chunk.Length);
}
}
Console.WriteLine($"\nFile saved as: received_{fileName}");
}
catch (Exception ex)
{
Console.WriteLine($"UDP File Client error: {ex.Message}");
}
finally
{
udpClient?.Close();
}
}
// 9. UDP Chat Server (connectionless chat)
public static async Task UdpChatServer()
{
Console.WriteLine("\n=== UDP Chat Server ===");
int port = 9094;
UdpClient udpServer = null;
var clients = new System.Collections.Generic.Dictionary<string, IPEndPoint>();
try
{
udpServer = new UdpClient(port);
Console.WriteLine($"UDP Chat Server started on port {port}");
while (true)
{
var result = await udpServer.ReceiveAsync();
string message = Encoding.UTF8.GetString(result.Buffer);
IPEndPoint senderEndPoint = result.RemoteEndPoint;
// Handle different message types
if (message.StartsWith("JOIN:"))
{
string username = message.Substring(5);
string clientKey = $"{senderEndPoint.Address}:{senderEndPoint.Port}";
clients[clientKey] = senderEndPoint;
Console.WriteLine($"{username} joined the chat");
// Notify all clients
string joinMessage = $"SYSTEM:{username} joined the chat";
await BroadcastToAllClients(udpServer, joinMessage, clients, null);
}
else if (message.StartsWith("LEAVE:"))
{
string username = message.Substring(6);
string clientKey = $"{senderEndPoint.Address}:{senderEndPoint.Port}";
clients.Remove(clientKey);
Console.WriteLine($"{username} left the chat");
string leaveMessage = $"SYSTEM:{username} left the chat";
await BroadcastToAllClients(udpServer, leaveMessage, clients, null);
}
else if (message.StartsWith("CHAT:"))
{
string chatMessage = message.Substring(5);
string clientKey = $"{senderEndPoint.Address}:{senderEndPoint.Port}";
if (clients.ContainsKey(clientKey))
{
Console.WriteLine($"Chat message: {chatMessage}");
await BroadcastToAllClients(udpServer, $"MSG:{chatMessage}", clients, senderEndPoint);
}
}
}
}
catch (Exception ex)
{
Console.WriteLine($"UDP Chat Server error: {ex.Message}");
}
finally
{
udpServer?.Close();
}
}
static async Task BroadcastToAllClients(UdpClient udpClient, string message,
System.Collections.Generic.Dictionary<string, IPEndPoint> clients, IPEndPoint exclude)
{
byte[] messageBytes = Encoding.UTF8.GetBytes(message);
foreach (var client in clients.Values)
{
if (exclude == null || !client.Equals(exclude))
{
try
{
await udpClient.SendAsync(messageBytes, messageBytes.Length, client);
}
catch
{
// Client might be disconnected
}
}
}
}
// 10. UDP Chat Client
public static async Task UdpChatClient(string username, string serverIp = "127.0.0.1", int port = 9094)
{
Console.WriteLine("\n=== UDP Chat Client ===");
UdpClient udpClient = null;
try
{
udpClient = new UdpClient();
IPEndPoint serverEndPoint = new IPEndPoint(IPAddress.Parse(serverIp), port);
// Join chat
string joinMessage = $"JOIN:{username}";
byte[] joinBytes = Encoding.UTF8.GetBytes(joinMessage);
await udpClient.SendAsync(joinBytes, joinBytes.Length, serverEndPoint);
// Start receiving messages
_ = Task.Run(async () =>
{
while (true)
{
var result = await udpClient.ReceiveAsync();
string message = Encoding.UTF8.GetString(result.Buffer);
if (message.StartsWith("SYSTEM:"))
{
Console.WriteLine($"\n{message.Substring(7)}");
}
else if (message.StartsWith("MSG:"))
{
Console.WriteLine($"\n{message.Substring(4)}");
}
}
});
// Send messages
Console.WriteLine("Type messages (type 'quit' to exit):");
while (true)
{
string input = Console.ReadLine();
if (string.IsNullOrEmpty(input)) continue;
if (input.ToLower() == "quit")
{
string leaveMessage = $"LEAVE:{username}";
byte[] leaveBytes = Encoding.UTF8.GetBytes(leaveMessage);
await udpClient.SendAsync(leaveBytes, leaveBytes.Length, serverEndPoint);
break;
}
string chatMessage = $"CHAT:{input}";
byte[] messageBytes = Encoding.UTF8.GetBytes(chatMessage);
await udpClient.SendAsync(messageBytes, messageBytes.Length, serverEndPoint);
}
}
catch (Exception ex)
{
Console.WriteLine($"UDP Chat Client error: {ex.Message}");
}
finally
{
udpClient?.Close();
}
}
// 11. UDP Discovery Service
public static async Task UdpDiscoveryService()
{
Console.WriteLine("\n=== UDP Discovery Service ===");
int port = 9095;
UdpClient discoveryServer = null;
try
{
discoveryServer = new UdpClient();
discoveryServer.EnableBroadcast = true;
discoveryServer.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
discoveryServer.Client.Bind(new IPEndPoint(IPAddress.Any, port));
Console.WriteLine($"UDP Discovery Service listening on port {port}");
while (true)
{
var result = await discoveryServer.ReceiveAsync();
string message = Encoding.UTF8.GetString(result.Buffer);
IPEndPoint clientEndPoint = result.RemoteEndPoint;
if (message == "DISCOVER")
{
Console.WriteLine($"Discovery request from {clientEndPoint}");
// Respond with service information
string response = $"SERVICE:MyApp:127.0.0.1:8080:{DateTime.Now:O}";
byte[] responseBytes = Encoding.UTF8.GetBytes(response);
await discoveryServer.SendAsync(responseBytes, responseBytes.Length, clientEndPoint);
}
}
}
catch (Exception ex)
{
Console.WriteLine($"Discovery Service error: {ex.Message}");
}
finally
{
discoveryServer?.Close();
}
}
// 12. UDP Discovery Client
public static async Task UdpDiscoveryClient(int port = 9095)
{
Console.WriteLine("\n=== UDP Discovery Client ===");
UdpClient udpClient = null;
try
{
udpClient = new UdpClient();
udpClient.EnableBroadcast = true;
// Send discovery broadcast
string discoveryMessage = "DISCOVER";
byte[] discoveryBytes = Encoding.UTF8.GetBytes(discoveryMessage);
IPAddress broadcastAddress = IPAddress.Broadcast;
IPEndPoint broadcastEndPoint = new IPEndPoint(broadcastAddress, port);
Console.WriteLine("Sending discovery broadcast...");
await udpClient.SendAsync(discoveryBytes, discoveryBytes.Length, broadcastEndPoint);
// Collect responses
var responses = new System.Collections.Generic.List<string>();
var endTime = DateTime.Now.AddSeconds(5);
while (DateTime.Now < endTime)
{
var receiveTask = udpClient.ReceiveAsync();
var timeoutTask = Task.Delay(500);
var completedTask = await Task.WhenAny(receiveTask, timeoutTask);
if (completedTask == receiveTask)
{
var response = await receiveTask;
string responseMessage = Encoding.UTF8.GetString(response.Buffer);
responses.Add($"From {response.RemoteEndPoint}: {responseMessage}");
}
}
Console.WriteLine($"\nFound {responses.Count} services:");
foreach (string response in responses)
{
Console.WriteLine(response);
}
}
catch (Exception ex)
{
Console.WriteLine($"Discovery Client error: {ex.Message}");
}
finally
{
udpClient?.Close();
}
}
static async Task Main(string[] args)
{
Console.WriteLine("=== C# UDP Socket Demo ===\n");
try
{
Console.WriteLine("Choose which demo to run:");
Console.WriteLine("1. Simple UDP Server/Client");
Console.WriteLine("2. Broadcast");
Console.WriteLine("3. Multicast");
Console.WriteLine("4. File Transfer");
Console.WriteLine("5. Chat");
Console.WriteLine("6. Discovery");
// Run a simple demo
Console.WriteLine("\nStarting simple UDP server on port 9090...");
_ = Task.Run(() => SimpleUdpServer());
await Task.Delay(1000);
Console.WriteLine("Starting UDP client to send messages...");
await SimpleUdpClient();
Console.WriteLine("\nUDP socket demos completed!");
}
catch (Exception ex)
{
Console.WriteLine($"Error in UDP demo: {ex.Message}");
}
}
}Tools
Tools frequently paired with this sample
Related