Windows Netzwerkprogrammierung - C# Beispiele

Umfassende C# Netzwerkprogrammierbeispiele für Windows-Plattform einschließlich HTTP-Anfragen, TCP-Sockets, UDP-Kommunikation und Webserver-Implementierung

💻 HTTP-Anfragen mit HttpClient csharp

🟢 simple ⭐⭐

HTTP GET, POST, PUT, DELETE Anfragen mit C# HttpClient machen, einschließlich Fehlerbehandlung und asynchroner Operationen

⏱️ 25 min 🏷️ csharp, http, networking, async, rest api, windows
Prerequisites: C# async/await, HTTP protocol basics, JSON serialization
using System;
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 Programmierung csharp

🟡 intermediate ⭐⭐⭐

TCP-Clients und Server für bidirektionale Kommunikation mit C# Sockets erstellen

⏱️ 30 min 🏷️ 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 Programmierung csharp

🟡 intermediate ⭐⭐⭐

UDP-Client und Server-Implementierung für verbindungslose Kommunikation, Broadcast und Multicast

⏱️ 28 min 🏷️ 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}");
        }
    }
}