lundi 1 septembre 2025

Sockets

1️⃣ Concepts de base

Q1 : Qu’est-ce qu’un socket ?
R :
Un socket est un point de communication pour envoyer et recevoir des données sur un réseau. En C#, il se trouve dans l’espace de noms System.Net.Sockets. Il permet de créer des applications client/serveur utilisant TCP ou UDP.


Q2 : Différence entre TCP et UDP ?
R :

Critère TCP UDP
Fiabilité Fiable, connexion orientée Non fiable, sans connexion
Vitesse Plus lent (retransmissions) Plus rapide, pas de garantie
Utilisation Email, HTTP, FTP Streaming vidéo/audio, jeux en temps réel

Q3 : Quels sont les types de sockets disponibles en C# ?
R :

  • SocketType.Stream → TCP

  • SocketType.Dgram → UDP

  • SocketType.Raw → accès bas-niveau (rare)

  • ProtocolType.Tcp, ProtocolType.Udp, etc.


2️⃣ Création et utilisation d’un socket

Q4 : Comment créer un socket TCP en C# ?

using System.Net;
using System.Net.Sockets;

Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

Q5 : Comment lier un socket à un port et écouter les connexions ?

IPEndPoint endPoint = new IPEndPoint(IPAddress.Any, 8080);
server.Bind(endPoint);
server.Listen(10); // max 10 connexions en file d'attente
Socket client = server.Accept(); // bloque jusqu'à connexion client

Q6 : Différence entre Socket et TcpClient / TcpListener ?

  • Socket → bas niveau, plus flexible

  • TcpClient / TcpListener → couche plus haute, simplifie l’envoi/réception de données


3️⃣ Envoi et réception de données

Q7 : Comment envoyer des données via un socket TCP ?

byte[] data = Encoding.UTF8.GetBytes("Hello Client");
client.Send(data);

Q8 : Comment recevoir des données ?

byte[] buffer = new byte[1024];
int received = client.Receive(buffer);
string message = Encoding.UTF8.GetString(buffer, 0, received);

Q9 : Différence entre Send/Receive et SendTo/ReceiveFrom ?

  • Send / Receive → TCP, connexion orientée

  • SendTo / ReceiveFrom → UDP, pas de connexion préalable


4️⃣ Asynchrone et multi-threading

Q10 : Comment gérer plusieurs clients ?

  • Option 1 : Multi-threading (nouveau thread par client)

  • Option 2 : BeginAccept / EndAccept pour programmation asynchrone

  • Option 3 : async/await avec TcpClient et NetworkStream

client.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), client);

Q11 : Avantages des sockets asynchrones ?

  • Ne bloque pas le thread principal

  • Permet de gérer beaucoup de clients simultanément

  • Réduit l’usage de threads par client


5️⃣ Questions avancées / scénarios

Q12 : Qu’est-ce que SocketOptionName et pourquoi l’utiliser ?

  • Permet de configurer le comportement du socket

  • Exemples :

    • NoDelay → désactiver Nagle (TCP_NODELAY)

    • ReuseAddress → réutiliser un port sans attendre


Q13 : Comment gérer les timeout d’envoi et de réception ?

client.ReceiveTimeout = 5000; // 5 secondes
client.SendTimeout = 5000;

Q14 : Comment fermer proprement un socket ?

client.Shutdown(SocketShutdown.Both);
client.Close();

Q15 : Différence entre Shutdown et Close ?

  • Shutdown → termine la transmission (lecture/écriture) mais garde le socket ouvert

  • Close → libère les ressources du socket


Q16 : Comment détecter qu’un client s’est déconnecté ?

  • Receive retourne 0 octet → le client a fermé la connexion

  • Peut aussi utiliser exceptions (SocketException) pour les erreurs réseau


Q17 : Sécurité / SSL avec sockets ?

  • SslStream sur un NetworkStream permet de sécuriser un socket TCP avec TLS/SSL




Un exemple complet en C# d’un serveur TCP multi-client utilisant async/await et un client simple pour test.


1️⃣ Serveur TCP asynchrone multi-client

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;

class TcpServer
{
    private TcpListener listener;

    public TcpServer(string ip, int port)
    {
        listener = new TcpListener(IPAddress.Parse(ip), port);
    }

    public async Task StartAsync()
    {
        listener.Start();
        Console.WriteLine("Server started...");

        while (true)
        {
            TcpClient client = await listener.AcceptTcpClientAsync();
            Console.WriteLine("Client connected.");
            _ = HandleClientAsync(client); // fire-and-forget
        }
    }

    private async Task HandleClientAsync(TcpClient client)
    {
        using (client)
        {
            NetworkStream stream = client.GetStream();
            byte[] buffer = new byte[1024];
            int bytesRead;

            try
            {
                while ((bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length)) != 0)
                {
                    string message = Encoding.UTF8.GetString(buffer, 0, bytesRead);
                    Console.WriteLine($"Received: {message}");

                    string response = "Server: " + message.ToUpper();
                    byte[] data = Encoding.UTF8.GetBytes(response);
                    await stream.WriteAsync(data, 0, data.Length);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("Client disconnected: " + ex.Message);
            }
        }
    }
}

2️⃣ Client TCP simple

using System;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;

class TcpClientExample
{
    public static async Task StartClientAsync(string ip, int port)
    {
        using TcpClient client = new TcpClient();
        await client.ConnectAsync(ip, port);
        Console.WriteLine("Connected to server.");

        NetworkStream stream = client.GetStream();

        while (true)
        {
            Console.Write("Enter message: ");
            string message = Console.ReadLine();
            if (string.IsNullOrEmpty(message)) break;

            byte[] data = Encoding.UTF8.GetBytes(message);
            await stream.WriteAsync(data, 0, data.Length);

            byte[] buffer = new byte[1024];
            int bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length);
            string response = Encoding.UTF8.GetString(buffer, 0, bytesRead);
            Console.WriteLine(response);
        }
    }
}

3️⃣ Programme principal pour tester

using System;
using System.Threading.Tasks;

class Program
{
    static async Task Main(string[] args)
    {
        Console.WriteLine("Start as Server or Client? (s/c)");
        string choice = Console.ReadLine().ToLower();

        if (choice == "s")
        {
            TcpServer server = new TcpServer("127.0.0.1", 9000);
            await server.StartAsync();
        }
        else if (choice == "c")
        {
            await TcpClientExample.StartClientAsync("127.0.0.1", 9000);
        }
        else
        {
            Console.WriteLine("Invalid choice.");
        }
    }
}

Caractéristiques de cet exemple :

  • Serveur capable de gérer plusieurs clients simultanément grâce à async/await.

  • Chaque client peut envoyer des messages et recevoir une réponse transformée.

  • Utilisation de NetworkStream pour lecture/écriture.

  • Gestion propre de la déconnexion des clients.


Return

Aucun commentaire:

Enregistrer un commentaire

Sockets Lượt xem: