Comunicación entre cliente y servidor

Principios básicos

Una vez establecida la conexión TCP, los datos circulan a través de NetworkStream (flujo de red);
La red solo trabaja con arreglos de bytes byte[]. El texto debe codificarse previamente a bytes y, al recibirlo, se decodifica para reconstruir la cadena original.

No solo se transmite texto: también archivos e imágenes se pueden convertir a arreglos de bytes para enviarse. En esta sección primero implementamos un chat de texto.

Explicación de las API principales

  1. Lado del servidor
    listener.AcceptTcpClient()
  • Método de bloqueo (espera suspendida): el hilo se detiene en esta línea hasta que algún cliente solicite una conexión;
  • Devuelve un objeto TcpClient que representa esa conexión de cliente;
  • Obtenemos el flujo de red mediante tcpClient.GetStream().
  1. Lectura y escritura sobre el flujo de red
  • stream.Write(arreglo de bytes, posición inicial, longitud): Enviar datos
  • stream.Read(arreglo búfer, posición inicial, longitud máxima de lectura): Recibir datos, retorna la cantidad real de bytes leídos
  1. Consideraciones sobre la codificación
    Los ejemplos del curso usan Encoding.Unicode (UTF‑16). El emisor y el receptor deben usar exactamente la misma codificación, si no aparecerán caracteres corruptos.

Servidor WinForms

Controles:
textBoxIP, textBoxPort, textBoxInfo (cuadro de mensajes)

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;
        }
    }
}Lenguaje del código: PHP (php)

Cliente WinForms

Controles:
textBoxIP, textBoxPort, textBoxInfo, textBoxInput (cuadro de entrada)
buttonStart【Conectar】, buttonSend【Enviar】

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);
        }
    }
}Lenguaje del código: PHP (php)

Este código implementa el envío de mensajes entre cliente y servidor.

Comunicación entre cliente y servidor

Previous:

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *