Envoi continu depuis le client

Nous allons modifier la partie serveur de la section précédente pour recevoir en continu les messages envoyés par le client, tout en activant le multi‑threading.

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Windows.Forms;

namespace TcpServerDemo
{
    public partial class Form1 : Form
    {
        private TcpListener listener;
        private TcpClient tcpClient;

        public Form1()
        {
            InitializeComponent();
            Control.CheckForIllegalCrossThreadCalls = false;
        }

        private void btnStartServer_Click(object sender, EventArgs e)
        {
            Thread acceptThread = new Thread(() =>
            {
                IPAddress ip = IPAddress.Parse(this.textBoxIP.Text);//Création de l'adresse IP
                listener = new TcpListener(ip, Convert.ToInt32(this.textBoxPort.Text));//Instanciation de l'écouteur TCP
                listener.Start();
                this.textBoxInfo.Text = "Serveur démarré‑" + DateTime.Now.ToShortTimeString() + "\r\n" + this.textBoxInfo.Text;
                tcpClient = listener.AcceptTcpClient();//Appel bloquant, attente de connexion
                this.textBoxInfo.Text = "Connexion établie‑" + DateTime.Now.ToShortTimeString() + "\r\n" + this.textBoxInfo.Text;

                NetworkStream stream = tcpClient.GetStream();
                byte[] byteArray = new byte[1024];
                while (true)
                {
                    int length = stream.Read(byteArray, 0, 1024);//Lit les octets du flux dans le tampon byteArray
                    //length correspond au nombre réel d'octets transmis par le client
                    string receiveMessage = Encoding.Unicode.GetString(byteArray, 0, length);
                    this.textBoxInfo.Text = "Reçu:" + receiveMessage + "-" +
                        DateTime.Now.ToShortTimeString() + "\r\n" + this.textBoxInfo.Text;
                }
            });
            acceptThread.IsBackground = true;
            acceptThread.Start();
        }
    }
}Langage du code : C# (cs)

Réalisation basée sur WinForms + TcpClient / TcpListener:
Le client envoie continuellement du texte personnalisé ; saisissez【Quitter】pour fermer la connexion et arrêter le programme

Ce code démo utilise une astuce simple pour contourner le gel de l’interface lié au multi‑threading. Cependant la bonne pratique est présentée ci‑dessous:
Control.CheckForIllegalCrossThreadCalls = false; est une méthode brutale déconseillée. Dans un projet de production, utilisez Invoke/BeginInvoke pour mettre à jour les contrôles depuis un autre thread.

1. Côté serveur

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Windows.Forms;

namespace TcpServerDemo
{
    public partial class Form1 : Form
    {
        private TcpListener listener;
        private TcpClient tcpClient;

        public Form1()
        {
            InitializeComponent();
            // Réservé à l'apprentissage, à éviter en production
            Control.CheckForIllegalCrossThreadCalls = false;
        }

        private void btnStartServer_Click(object sender, EventArgs e)
        {
            // Création d’un nouveau thread pour ne pas bloquer l’interface
            new Thread(() =>
            {
                IPAddress ip = IPAddress.Parse(textBoxIP.Text);
                listener = new TcpListener(ip, Convert.ToInt32(textBoxPort.Text));
                listener.Start();
                AppendLog($"Serveur démarré‑{DateTime.Now.ToShortTimeString()}");

                tcpClient = listener.AcceptTcpClient();
                AppendLog($"Client connecté‑{DateTime.Now.ToShortTimeString()}");

                NetworkStream stream = tcpClient.GetStream();
                byte[] byteArray = new byte[1024];
                while (true)
                {
                    int length = stream.Read(byteArray, 0, 1024);
                    if (length <= 0)
                    {
                        AppendLog("Le client a rompu la connexion");
                        break;
                    }
                    string receiveMessage = Encoding.Unicode.GetString(byteArray, 0, length);
                    AppendLog($"Reçu:{receiveMessage}{DateTime.Now.ToShortTimeString()}");
                }
                tcpClient.Close();
                listener.Stop();
            }).Start();
        }

        // Ajoute une ligne de journal dans la zone de texte
        private void AppendLog(string msg)
        {
            textBoxInfo.Text = msg + "\r\n" + textBoxInfo.Text;
        }
    }
}Langage du code : C# (cs)

2. Code côté client

Implémente une saisie continue ; taper «Quitter» met fin aux échanges

Contrôles à prévoir sur le formulaire client:

  • textBoxServerIp:Adresse IP du serveur
  • textBoxPort:Numéro de port
  • textBoxSend:Champ de saisie des messages à envoyer
  • btnConnect:Bouton de connexion
  • btnSend:Bouton d’envoi
using System;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Windows.Forms;

namespace TcpClientDemo
{
    public partial class ClientForm : Form
    {
        private TcpClient client;
        private NetworkStream stream;
        private bool isConnected = false;

        public ClientForm()
        {
            InitializeComponent();
            Control.CheckForIllegalCrossThreadCalls = false;
        }

        // Connexion au serveur
        private void btnConnect_Click(object sender, EventArgs e)
        {
            try
            {
                client = new TcpClient();
                client.Connect(textBoxServerIp.Text, Convert.ToInt32(textBoxPort.Text));
                stream = client.GetStream();
                isConnected = true;
                MessageBox.Show("Connexion établie, vous pouvez envoyer vos messages !");
            }
            catch (Exception ex)
            {
                MessageBox.Show("Échec de la connexion:" + ex.Message);
            }
        }

        // Logique principale d’envoi des messages
        private void btnSend_Click(object sender, EventArgs e)
        {
            if (!isConnected)
            {
                MessageBox.Show("Veuillez d’abord vous connecter au serveur !");
                return;
            }
            string content = textBoxSend.Text.Trim();
            if (string.IsNullOrEmpty(content))
                return;

            // Détection de la commande de sortie
            if (content == "Quitter")
            {
                byte[] exitData = Encoding.Unicode.GetBytes(content);
                stream.Write(exitData, 0, exitData.Length);

                // Libération des ressources
                stream.Close();
                client.Close();
                isConnected = false;
                MessageBox.Show("Connexion terminée");
                return;
            }

            // Envoi d’un message personnalisé
            byte[] data = Encoding.Unicode.GetBytes(content);
            stream.Write(data, 0, data.Length);
            textBoxSend.Clear();
        }
    }
}Langage du code : C# (cs)
static void Main(string[] args)
{
    TcpClient client = new TcpClient();
    client.Connect("127.0.0.1", 8899);
    NetworkStream stream = client.GetStream();
    while (true)
    {
        Console.Write("Saisissez votre message:");
        string msg = Console.ReadLine();
        byte[] buf = Encoding.Unicode.GetBytes(msg);
        stream.Write(buf,0,buf.Length);
        if (msg == "Quitter")
        {
            stream.Close();
            client.Close();
            break;
        }
    }
}Langage du code : JavaScript (javascript)

Si vous le souhaitez, je peux réécrire l’ensemble du code selon le schéma async/await entièrement asynchrone, pour supprimer complètement les threads secondaires ainsi que la mauvaise pratique de désactiver la vérification des appels inter‑threads.

Envoi continu depuis le client

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *