Nesta lição, vamos criar um cliente que fará a conexão com o lado do servidor.
Com base no código do servidor da lição anterior (TcpListener) e no cliente desta seção (TcpClient), vamos implementar passo a passo uma ferramenta de bate‑papo TCP.
Diferença de conceitos
- Servidor: TcpListener
Faz o bind em um IP fixo e na porta fixa 9500. Ele fica escutando de forma passiva aguardando clientes, aceitando múltiplas conexões simultâneas. Funciona como um vendedor que espera os compradores chegarem. - Cliente: TcpClient
Não é necessário definir uma porta manualmente. O sistema operacional atribui automaticamente uma porta temporária aleatória para iniciar a conexão com a porta 9500 do servidor.
As portas dos dois lados da comunicação não são iguais
Porta aleatória do cliente — porta fixa do servidor 9500
Cliente de console
using System;
using System.Net.Sockets;
namespace TalkClient
{
class Program
{
static void Main(string[] args)
{
// Instancia o objeto cliente TCP
TcpClient tcpClient = new TcpClient();
// Inicia conexão com o servidor local 127.0.0.1:9500
// Para outro computador, informe o IP dele; servidor e cliente não precisam estar na mesma máquina
tcpClient.Connect("127.0.0.1", 9500);
// LocalEndPoint: endereço e porta locais do cliente
// RemoteEndPoint: endereço e porta do servidor remoto
Console.WriteLine("Conexão estabelecida, porta local {0}, porta do servidor {1}",
tcpClient.Client.LocalEndPoint,
tcpClient.Client.RemoteEndPoint);
Console.ReadLine();
tcpClient.Close();
}
}
}Code language: JavaScript (javascript)
Código do cliente WinForms
Controles da interface:
textBoxIP: IP do servidortextBoxPort: Porta do servidorbuttonStart: Botão de conectartextBoxInfo: Caixa de exibição de mensagenstextBoxMsg: Campo de entrada para mensagens a serem enviadasbuttonSend: Botão de envio
using System;
using System.Net.Sockets;
using System.Windows.Forms;
namespace SocketChatClient
{
public partial class Form1 : Form
{
TcpClient tcpClient;
public Form1()
{
InitializeComponent();
}
// Evento de clique no botão conectar
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($"Conexão realizada com sucesso! Endpoint local: {tcpClient.Client.LocalEndPoint}\r\n");
}
catch (Exception ex)
{
MessageBox.Show("Falha na conexão‑" + ex.Message);
}
}
}
}Code language: PHP (php)
Interação entre servidor e cliente
- Inicie primeiro o programa do servidor, clique em iniciar e chame
TcpListener.Start()para começar a escutar a porta 9500 - Depois execute o programa cliente, clique em conectar;
TcpClient.Connect()executa o handshake de três vias do TCP - Após a conexão, as mensagens são trocadas nos dois sentidos por meio de
NetworkStream(assunto do próximo capítulo)
Observações importantes
- Causas comuns de falha de conexão
- Ordem errada: o servidor não foi iniciado antes
- IP ou porta informados não correspondem
- Bloqueio do firewall; ao depurar entre máquinas diferentes evite
127.0.0.1, use o IP da rede local
- Conhecimento sobre portas
- O servidor mantém a porta 9500 fixa e aceita vários clientes ao mesmo tempo
- A porta do cliente é atribuída aleatoriamente pelo sistema operacional, muda a cada execução e não precisa ser definida manualmente
- Aviso sobre bloqueio de thread
Chamar diretamente.Connect()em aplicações com interface trava a thread da UI. Em projetos reais prefira o método assíncronoConnectAsyncpara evitar que a janela pare de responder.
Revisão: Servidor WinForms (lição anterior)
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 = $"Servidor iniciado {DateTime.Now.ToShortTimeString()}\r\n" + textBoxInfo.Text;
}
}
}Code language: C# (cs)
Cliente