Principes fondamentaux
Une fois la connexion TCP établie, les données transitent via le NetworkStream ;
Le réseau ne peut transmettre que des tableaux d’octets byte[]. Le texte doit d’abord être encodé en octets, puis décodé pour retrouver la chaîne de caractères à la réception.
La transmission ne se limite pas au texte : fichiers et images peuvent aussi être convertis en tableaux d’octets. Cette section implémente d’abord un chat textuel.
Description des API clés
- Côté serveur
listener.AcceptTcpClient()
- Méthode bloquante (attente interrompue) : le thread se met en pause jusqu’à ce qu’un client initie une connexion ;
- Retourne un objet
TcpClientqui représente cette connexion client ; - Récupérez le flux réseau avec
tcpClient.GetStream().
- Lecture‑écriture du flux réseau
stream.Write(tableau d'octets, décalage, longueur): Envoyer des donnéesstream.Read(tableau tampon, décalage, longueur max de lecture): Recevoir des données, renvoie le nombre réel d’octets lus
- Attention à l’encodage
Les exemples du cours utilisentEncoding.Unicode(UTF‑16). L’encodage doit être identique côté émetteur et côté récepteur, sinon des caractères indésirables apparaîtront.
Serveur WinForms
Contrôles :textBoxIP, textBoxPort, textBoxInfo (zone d’affichage des messages)
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Windows.Forms;
namespace TcpServer
{
public partial class Form1 : Form
{
IPAddress ip;
TcpListener listener;
TcpClient tcpClient;
public Form1()
{
InitializeComponent();
}
private void buttonStart_Click(object sender, EventArgs e)
{
ip = IPAddress.Parse(textBoxIP.Text);
listener = new TcpListener(ip, Convert.ToInt32(textBoxPort.Text));
listener.Start();
textBoxInfo.Text = $"服务器启动-{DateTime.Now.ToShortTimeString()}\r\n" + textBoxInfo.Text;
// 阻塞!主线程卡住
tcpClient = listener.AcceptTcpClient();
textBoxInfo.Text = $"连接成功-{DateTime.Now.ToShortTimeString()}\r\n" + textBoxInfo.Text;
NetworkStream stream = tcpClient.GetStream();
byte[] byteArray = new byte[1024];
// 阻塞等待客户端发送消息
int length = stream.Read(byteArray, 0, 1024);
string receiveMessage = Encoding.Unicode.GetString(byteArray, 0, length);
textBoxInfo.Text = $"接收到:{receiveMessage}-{DateTime.Now.ToShortTimeString()}\r\n" + textBoxInfo.Text;
}
}
}Langage du code : PHP (php)
Client WinForms
Contrôles :textBoxIP, textBoxPort, textBoxInfo, textBoxInput (champ de saisie)buttonStart【Connexion】, buttonSend【Envoyer】
using System;
using System.Net.Sockets;
using System.Text;
using System.Windows.Forms;
namespace TcpClientChat
{
public partial class Form1 : Form
{
TcpClient tcpClient;
public Form1()
{
InitializeComponent();
}
private void buttonStart_Click(object sender, EventArgs e)
{
tcpClient = new TcpClient();
try
{
tcpClient.Connect(textBoxIP.Text, Convert.ToInt32(textBoxPort.Text));
textBoxInfo.AppendText("连接成功!\r\n");
}
catch (Exception ex)
{
MessageBox.Show("连接失败-" + ex.Message);
}
}
private void buttonSend_Click(object sender, EventArgs e)
{
string message = textBoxInput.Text;
textBoxInfo.Text = $"发送“{message}”-{DateTime.Now.ToShortTimeString()}\r\n" + textBoxInfo.Text;
NetworkStream stream = tcpClient.GetStream();
byte[] byteArray = Encoding.Unicode.GetBytes(message);
stream.Write(byteArray, 0, byteArray.Length);
}
}
}Langage du code : PHP (php)
Ce code implémente l’envoi de messages entre client et serveur.
Communication client‑serveur