In dieser Lektion erstellen wir einen Client, der anschließend eine Verbindung zum Server aufbaut.
Mit dem Server‑Code aus der vorherigen Einheit (TcpListener) und dem Client aus diesem Abschnitt (TcpClient) bauen wir Schritt für Schritt ein TCP‑Chat‑Tool auf.
Begriffe im Überblick
- Server: TcpListener
Bindet sich an eine feste IP‑Adresse und den festen Port 9500. Er lauscht dauerhaft passiv und wartet auf eingehende Client‑Verbindungen, mehrere Clients können gleichzeitig akzeptiert werden. Man kann es mit einem Händler vergleichen, der auf seine Kunden wartet. - Client: TcpClient
Ein manuelles Binden an einen Port ist nicht erforderlich. Das Betriebssystem weist automatisch einen zufälligen temporären Port zu und baut eine aktive Verbindung zum festen Server‑Port 9500 auf.
Die Ports der Kommunikationspartner stimmen nicht überein
Zufälliger Client‑Port — fester Server‑Port 9500
Konsolen‑Client
using System;
using System.Net.Sockets;
namespace TalkClient
{
class Program
{
static void Main(string[] args)
{
// TCP‑Client‑Objekt erzeugen
TcpClient tcpClient = new TcpClient();
// Verbindung zum lokalen Server 127.0.0.1:9500 herstellen
// Bei anderen Rechnern die entsprechende IP eintragen, Server und Client müssen nicht auf dem gleichen PC laufen
tcpClient.Connect("127.0.0.1", 9500);
// LocalEndPoint: Lokale Adresse und Port des Clients
// RemoteEndPoint: Adresse und Port des entfernten Servers
Console.WriteLine("Verbindung hergestellt. Lokaler Port {0}, Server‑Port {1}",
tcpClient.Client.LocalEndPoint,
tcpClient.Client.RemoteEndPoint);
Console.ReadLine();
tcpClient.Close();
}
}
}Code-Sprache: JavaScript (javascript)
WinForms‑Client‑Quellcode
Steuerelemente der Oberfläche:
textBoxIP: Server‑IP‑AdressetextBoxPort: Server‑PortnummerbuttonStart: Schalter zum Herstellen der VerbindungtextBoxInfo: Anzeigefeld für NachrichtentextBoxMsg: Eingabefeld für zu sendende NachrichtenbuttonSend: Sende‑Schalter
using System;
using System.Net.Sockets;
using System.Windows.Forms;
namespace SocketChatClient
{
public partial class Form1 : Form
{
TcpClient tcpClient;
public Form1()
{
InitializeComponent();
}
// Klick‑Ereignis des Verbindungsschalters
private void buttonStart_Click(object sender, EventArgs e)
{
tcpClient = new TcpClient();
try
{
string ip = textBoxIP.Text;
int port = Convert.ToInt32(textBoxPort.Text);
tcpClient.Connect(ip, port);
textBoxInfo.AppendText($"Verbindung erfolgreich! Lokaler Endpunkt: {tcpClient.Client.LocalEndPoint}\r\n");
}
catch (Exception ex)
{
MessageBox.Show("Verbindung fehlgeschlagen‑" + ex.Message);
}
}
}
}Code-Sprache: PHP (php)
Zusammenspiel von Server und Client
- Zuerst das Server‑Programm starten, Start‑Schalter betätigen, mit
TcpListener.Start()die Überwachung von Port 9500 beginnen - Anschließend das Client‑Programm starten, Verbindungsschalter betätigen,
TcpClient.Connect()führt den TCP‑Drei‑Wege‑Handshake durch - Nach erfolgreicher Verbindung erfolgt der bidirektionale Nachrichtenaustausch über
NetworkStream(Inhalt des nächsten Kapitels)
Hinweise
- Häufige Gründe für fehlgeschlagene Verbindungen
- Falsche Reihenfolge: Der Server wurde nicht zuerst gestartet
- IP‑Adresse oder Port stimmen nicht überein
- Firewall blockiert den Verkehr; Beim Debuggen über mehrere Rechner
127.0.0.1vermeiden, stattdessen die LAN‑IP verwenden
- Wissenswertes zu Ports
- Der Server nutzt fest den Port 9500, er kann mehrere Clients gleichzeitig bedienen
- Der Client‑Port wird vom Betriebssystem zufällig vergeben, er ändert sich bei jedem Start, eine manuelle Angabe ist nicht nötig
- Warnung vor blockierenden Aufrufen
Der direkte Aufruf von.Connect()in einer Form‑Anwendung blockiert den UI‑Thread. In Produktivprojekten sollte die asynchrone MethodeConnectAsyncverwendet werden, um ein Einfrieren des Fensters zu verhindern.
Rückblick: WinForms‑Server (vorherige Lektion)
using System;
using System.Net;
using System.Net.Sockets;
using System.Windows.Forms;
namespace SocketChatServer
{
public partial class Form1 : Form
{
IPAddress ip;
TcpListener listener;
public Form1()
{
InitializeComponent();
}
private void buttonStart_Click(object sender, EventArgs e)
{
ip = IPAddress.Parse(textBoxIP.Text);
int port = Convert.ToInt32(textBoxPort.Text);
listener = new TcpListener(ip, port);
listener.Start();
textBoxInfo.Text = $"Server gestartet {DateTime.Now.ToShortTimeString()}\r\n" + textBoxInfo.Text;
}
}
}Code-Sprache: C# (cs)
Client
Previous: Server‑seitige Port‑Überwachung