Fortlaufendes Senden auf Client‑Seite

Im Folgenden passen wir den serverseitigen Code aus dem vorherigen Abschnitt an. Der Server soll Nachrichten des Clients dauerhaft empfangen, zudem aktivieren wir die Multithreading‑Unterstützung.

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);//IP‑Adresse erstellen
                listener = new TcpListener(ip, Convert.ToInt32(this.textBoxPort.Text));//TCP‑Listener‑Objekt erzeugen
                listener.Start();
                this.textBoxInfo.Text = "Server gestartet‑" + DateTime.Now.ToShortTimeString() + "\r\n" + this.textBoxInfo.Text;
                tcpClient = listener.AcceptTcpClient();//blockierender Aufruf, wartet auf Verbindung
                this.textBoxInfo.Text = "Verbindung aufgebaut‑" + 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);//liest Bytes aus dem Stream in byteArray‑Puffer
                    //length gibt die tatsächliche Byte‑Anzahl der Client‑Nachricht an
                    string receiveMessage = Encoding.Unicode.GetString(byteArray, 0, length);
                    this.textBoxInfo.Text = "Empfangen:" + receiveMessage + "-" +
                        DateTime.Now.ToShortTimeString() + "\r\n" + this.textBoxInfo.Text;
                }
            });
            acceptThread.IsBackground = true;
            acceptThread.Start();
        }
    }
}Code-Sprache: C# (cs)

Realisierung mit WinForms + TcpClient / TcpListener:
Der Client sendet beliebige Texte fortlaufend an den Server. Gib 【Beenden】ein, um die Verbindung zu trennen und das Programm zu schließen

Dieses Demo umgeht Multithreading‑UI‑Hänger auf einfache Weise, die korrekte Vorgehensweise sieht aber so aus:
Control.CheckForIllegalCrossThreadCalls = false; ist eine nicht empfohlene grobe Notlösung. Für Produktivcode nutze Invoke/BeginInvoke um Steuerelemente aus fremden Threads zu aktualisieren.

1. Serverseite

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();
            // Nicht für Produktivprojekte, nur zu Lernzwecken
            Control.CheckForIllegalCrossThreadCalls = false;
        }

        private void btnStartServer_Click(object sender, EventArgs e)
        {
            // Neuer Thread um UI‑Blockaden zu vermeiden
            new Thread(() =>
            {
                IPAddress ip = IPAddress.Parse(textBoxIP.Text);
                listener = new TcpListener(ip, Convert.ToInt32(textBoxPort.Text));
                listener.Start();
                AppendLog($"Server gestartet‑{DateTime.Now.ToShortTimeString()}");

                tcpClient = listener.AcceptTcpClient();
                AppendLog($"Client verbunden‑{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("Client hat Verbindung getrennt");
                        break;
                    }
                    string receiveMessage = Encoding.Unicode.GetString(byteArray, 0, length);
                    AppendLog($"Empfangen:{receiveMessage}{DateTime.Now.ToShortTimeString()}");
                }
                tcpClient.Close();
                listener.Stop();
            }).Start();
        }

        // Log‑Zeile an Textbox anhängen
        private void AppendLog(string msg)
        {
            textBoxInfo.Text = msg + "\r\n" + textBoxInfo.Text;
        }
    }
}Code-Sprache: C# (cs)

2. Client‑Code

Funktion: fortlaufende Eingabe, Eingabe von „Beenden“ beendet die Kommunikation

Folgende Steuerelemente für das Client‑Formular vorsehen:

  • textBoxServerIp:IP‑Adresse des Servers
  • textBoxPort:Portnummer
  • textBoxSend:Eingabefeld für zu versendende Nachrichten
  • btnConnect:Verbindungs‑Button
  • btnSend:Sende‑Button
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;
        }

        // Verbindung zum Server aufbauen
        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("Verbindung hergestellt, du kannst jetzt Nachrichten senden!");
            }
            catch (Exception ex)
            {
                MessageBox.Show("Verbindungsfehler:" + ex.Message);
            }
        }

        // Kernlogik zum Senden von Nachrichten
        private void btnSend_Click(object sender, EventArgs e)
        {
            if (!isConnected)
            {
                MessageBox.Show("Zuerst mit dem Server verbinden!");
                return;
            }
            string content = textBoxSend.Text.Trim();
            if (string.IsNullOrEmpty(content))
                return;

            // Prüfen ob Beenden‑Befehl eingegeben wurde
            if (content == "Beenden")
            {
                byte[] exitData = Encoding.Unicode.GetBytes(content);
                stream.Write(exitData, 0, exitData.Length);

                // Ressourcen freigeben
                stream.Close();
                client.Close();
                isConnected = false;
                MessageBox.Show("Verbindung getrennt");
                return;
            }

            // Normalen Inhalt versenden
            byte[] data = Encoding.Unicode.GetBytes(content);
            stream.Write(data, 0, data.Length);
            textBoxSend.Clear();
        }
    }
}Code-Sprache: 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("Gib den zu sendenden Inhalt ein:");
        string msg = Console.ReadLine();
        byte[] buf = Encoding.Unicode.GetBytes(msg);
        stream.Write(buf,0,buf.Length);
        if (msg == "Beenden")
        {
            stream.Close();
            client.Close();
            break;
        }
    }
}Code-Sprache: JavaScript (javascript)

Bei Bedarf kann ich den gesamten Quellcode auf rein asynchrone async/await‑Syntax umschreiben. Dadurch verzichten wir komplett auf Hilfsthreads und die unsaubere Deaktivierung des Cross‑Thread‑Prüfers.

Fortlaufendes Senden auf Client‑Seite

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert