Comunicação entre cliente e servidor

Princípios fundamentais

Depois que a conexão TCP é estabelecida, os dados são transmitidos por meio do NetworkStream (fluxo de rede);
A rede só consegue trafegar arrays de bytes byte[]. Textos precisam ser convertidos para bytes antes do envio e decodificados de volta para string no recebimento.

A transmissão não se limita apenas a textos. Arquivos e imagens também podem ser convertidos em arrays de bytes para serem enviados. Nesta seção vamos implementar primeiro um bate‑papo de texto.

Explicação das APIs importantes

  1. Lado do servidor
    listener.AcceptTcpClient()
  • Método de bloqueio (espera suspensa): a thread fica parada nesse ponto até que um cliente inicie uma conexão;
  • Retorna um objeto TcpClient que representa essa conexão com o cliente;
  • Recuperamos o fluxo de rede com tcpClient.GetStream().
  1. Leitura e gravação no fluxo de rede
  • stream.Write(array de bytes, posição inicial, comprimento): Enviar dados
  • stream.Read(array buffer, posição inicial, comprimento máximo de leitura): Receber dados, devolve o número real de bytes lidos
  1. Avisos sobre codificação
    Os exemplos do curso utilizam Encoding.Unicode (UTF‑16). O emissor e o receptor devem usar a mesma codificação, caso contrário ocorrerão caracteres ilegíveis.

Servidor WinForms

Controles:
textBoxIP, textBoxPort, textBoxInfo (caixa de mensagens)

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;
        }
    }
}Code language: PHP (php)

Cliente WinForms

Controles:
textBoxIP, textBoxPort, textBoxInfo, textBoxInput (caixa 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);
        }
    }
}Code language: PHP (php)

O código acima realiza o envio de mensagens entre cliente e servidor.

Comunicação entre cliente e servidor

Previous:

Deixe um comentário

O seu endereço de email não será publicado. Campos obrigatórios marcados com *