用戶端TcpClient

這節課我們要建立用戶端,讓用戶端去連接伺服器端。

結合前一章的伺服器端(TcpListener)與本節的用戶端(TcpClient),一步步實作出一套 TCP 聊天工具。

觀念區分

  1. 伺服器端:TcpListener
    綁定固定 IP + 固定連接埠(9500),持續被動監聽,等候用戶端連入,可以同時接納多個用戶端。就好比店家,守在原地等待顧客上門。
  2. 用戶端:TcpClient
    不需要手動指定連接埠;作業系統會自動分配隨機的暫時連接埠,主動發起連線,去連接伺服器固定的 9500 連接埠。

通訊雙方的連接埠並不對等
用戶端隨機連接埠 — 伺服器固定 9500

主控台用戶端

using System;
using System.Net.Sockets;

namespace TalkClient
{
    class Program
    {
        static void Main(string[] args)
        {
            // 建立 TCP 用戶端物件
            TcpClient tcpClient = new TcpClient();

            // 發起連線,連接本機 127.0.0.1:9500 的伺服器。若是其他電腦,請填入目標電腦 IP,伺服器與用戶端不一定要在同一台機器。
            tcpClient.Connect("127.0.0.1", 9500);

            // LocalEndPoint:本機用戶端位址與連接埠
            // RemoteEndPoint:遠端伺服器位址與連接埠
            Console.WriteLine("連線成功,本機連接埠 {0},伺服器連接埠{1}",
                tcpClient.Client.LocalEndPoint,
                tcpClient.Client.RemoteEndPoint);

            Console.ReadLine();
            tcpClient.Close();
        }
    }
}Code language: JavaScript (javascript)

WinForms 用戶端程式碼

介面控制項:

  • textBoxIP:伺服器 IP
  • textBoxPort:伺服器連接埠
  • buttonStart:【連線】按鈕
  • textBoxInfo:訊息顯示區
  • textBoxMsg:待傳送訊息輸入欄
  • buttonSend:傳送按鈕
using System;
using System.Net.Sockets;
using System.Windows.Forms;

namespace SocketChatClient
{
    public partial class Form1 : Form
    {
        TcpClient tcpClient;

        public Form1()
        {
            InitializeComponent();
        }

        // 連線按鈕點擊事件
        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($"連線成功!本機端點:{tcpClient.Client.LocalEndPoint}\r\n");
            }
            catch (Exception ex)
            {
                MessageBox.Show("連線失敗‑" + ex.Message);
            }
        }
    }
}Code language: PHP (php)

伺服器端 + 用戶端配合流程

  1. 先啟動伺服器程式,點擊啟動,呼叫 TcpListener.Start() 開始監聽 9500 連接埠
  2. 接著啟動用戶端程式,點擊連線,透過 TcpClient.Connect() 完成 TCP 三次交握
  3. 連線建立完成後,雙向透過 NetworkStream 收發訊息(下一單元說明)

注意事項

  1. 連線失敗常見原因
  • 執行順序錯誤:沒有先開啟伺服器
  • IP / 連接埠設定不一致
  • 防火牆阻擋;跨電腦測試時不要用 127.0.0.1,改用區域網路 IP
  1. 連接埠相關知識
  • 伺服器固定使用 9500 連接埠,可同時處理多個用戶端連線
  • 用戶端連接埠由作業系統隨機指派,每次執行都會不一樣,無須手動設定
  1. 阻塞警告
    表單程式直接呼叫 .Connect() 會卡住 UI 執行緒。正式專案建議改用非同步的 ConnectAsync,避免視窗凍結。

回顧:伺服器端 WinForms(上一節)

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 = $"伺服器已啟動 {DateTime.Now.ToShortTimeString()}\r\n" + textBoxInfo.Text;
        }
    }
}Code language: C# (cs)

用戶端

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *