用戶端與伺服器通訊

核心原理

TCP 建立連線後,透過 NetworkStream(網路串流)傳輸資料;
網路僅能傳輸位元組陣列 byte[],文字必須先編碼為位元組,接收後再解碼還原成字串。

傳輸不限於文字,檔案、圖片同樣可轉換為位元組陣列進行傳送,本節先實作文字聊天功能。

關鍵 API 說明

  1. 伺服器端
    listener.AcceptTcpClient()
  • 封鎖方法(中斷等待):程式執行至此時執行緒暫停,直到用戶端發起連線;
  • 回傳 TcpClient 物件,代表該條用戶端連線;
  • 透過 tcpClient.GetStream() 取得網路串流。
  1. 網路串流讀寫
  • stream.Write(位元組陣列,起始位置,長度)傳送資料
  • stream.Read(快取陣列,起始位置,最大讀取長度)接收資料,回傳實際讀取到的位元組長度
  1. 編碼注意事項
    課程範例使用 Encoding.Unicode(UTF‑16),傳送與接收兩端編碼必須一致,否則會出現亂碼。

伺服器端 WinForms

控制項:
textBoxIPtextBoxPorttextBoxInfo(訊息顯示方塊)

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)

用戶端 WinForms

控制項:
textBoxIPtextBoxPorttextBoxInfotextBoxInput(輸入方塊)
buttonStart【連線】、buttonSend【傳送】

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)

以上程式碼實現用戶端與伺服器之間的訊息傳送。

用戶端與伺服器通訊

發佈留言

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