Unten ist die Implementierung eines bidirektionalen Chats mit Multithreading, um UI‑Blockaden zu vermeiden.
Die WinForm‑Version nutzt BackgroundWorker für die Empfangsschleife in einem separaten Thread, das Senden von Nachrichten läuft im UI‑Thread. Dadurch wird diese Einschränkung umgangen und uneingeschränkter bidirektionaler Chat ist möglich.
Zuerst der Server‑Code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Windows.Forms;
namespace Service
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
Control.CheckForIllegalCrossThreadCalls = false;
}
IPAddress ip;
TcpListener listener;
TcpClient tcpClient;
private void buttonStart_Click(object sender, EventArgs e)
{
this.backgroundWorker1.RunWorkerAsync();
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
ip = IPAddress.Parse(this.textBoxIP.Text);
listener = new TcpListener(ip, Convert.ToInt32(this.textBoxPort.Text));
listener.Start();
this.textBoxInfo.Text = "Server gestartet - " + DateTime.Now.ToShortTimeString() + "\r\n" + this.textBoxInfo.Text;
tcpClient = listener.AcceptTcpClient();
this.textBoxInfo.Text = "Verbindung hergestellt - " + 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);
string receiveMessage = Encoding.Unicode.GetString(byteArray, 0, length);
this.textBoxInfo.Text = "Empfangen: " + receiveMessage + " - " + DateTime.Now.ToShortTimeString() + "\r\n" + this.textBoxInfo.Text;
}
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
}
private void buttonSend_Click(object sender, EventArgs e)
{
string message = this.textBoxInput.Text;
this.textBoxInfo.Text = "Gesendet \"" + message + "\" - " + DateTime.Now.ToShortTimeString() + "\r\n" + this.textBoxInfo.Text;
NetworkStream stream = tcpClient.GetStream();
byte[] byteArray = Encoding.Unicode.GetBytes(message);
stream.Write(byteArray, 0, byteArray.Length);
}
}
}
Code-Sprache: C# (cs)
Anschließend der Client‑Code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Windows.Forms;
namespace Client
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
Control.CheckForIllegalCrossThreadCalls = false;
}
TcpClient tcpClient;
private void buttonStart_Click(object sender, EventArgs e)
{
tcpClient = new TcpClient();
try
{
tcpClient.Connect(this.textBoxIP.Text, Convert.ToInt32(this.textBoxPort.Text));
this.textBoxInfo.Text = "Verbindung hergestellt - " + DateTime.Now.ToShortTimeString() + "\r\n" + this.textBoxInfo.Text;
this.backgroundWorker1.RunWorkerAsync();
}
catch (Exception ex)
{
MessageBox.Show("Verbindungsfehler - "+ex.Message);
}
}
private void buttonSend_Click(object sender, EventArgs e)
{
string message = this.textBoxInput.Text;
this.textBoxInfo.Text = "Gesendet \""+message+"\" - " + DateTime.Now.ToShortTimeString() + "\r\n" + this.textBoxInfo.Text;
NetworkStream stream = tcpClient.GetStream();
byte[] byteArray = Encoding.Unicode.GetBytes(message);
stream.Write(byteArray, 0, byteArray.Length);
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
NetworkStream stream = tcpClient.GetStream();
byte[] byteArray = new byte[1024];
while (true)
{
int length = stream.Read(byteArray, 0, 1024);
string receiveMessage = Encoding.Unicode.GetString(byteArray, 0, length);
this.textBoxInfo.Text = "Empfangen: " + receiveMessage + " - " + DateTime.Now.ToShortTimeString() + "\r\n" + this.textBoxInfo.Text;
}
}
}
}
Code-Sprache: C# (cs)
Dauerhafter Chat
Previous: Fortlaufendes Senden auf Client‑Seite