首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

Socket 程式設計實戰 (二):TcpClient/TcpListener 高層封裝範例

     編輯:關於.NET

文章導讀

本文展示基於 TcpClient/TcpListener 與 NetworkStream/StreamReader/StreamWriter 的高層封裝範例,簡化資料讀寫為文字行導向操作。適合快速原型開發與教學參考。

核心知識點

  • TcpClient/TcpListener 簡化 Socket 操作
  • NetworkStream + StreamReader/Writer 文字流處理
  • 行導向協定:ReadLine/WriteLine + Flush
  • 伺服器端執行緒監聽與 STOP 指令優雅關閉

一、客戶端完整程式碼

using System.Windows.Forms;
using System.Net.Sockets;
using System.Threading;
using System.IO;
using System.Net;

namespace QQ
{
    public partial class Tcpclient : Form
    {
        private StreamWriter write;
        private NetworkStream stream;
        private TcpClient tcpclient;

        public Tcpclient() { InitializeComponent(); }

        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                tcpclient = new TcpClient(AddressFamily.InterNetwork);
                tcpclient.Connect("127.0.0.1", 8000); // 同步連線
                stream = tcpclient.GetStream(); // 取得網路串流
                write = new StreamWriter(stream); // 文字寫入器
                write.WriteLine(this.textBox1.Text); // 寫入一行 (含換行)
                write.Flush(); // 強制發送緩衝區
            }
            catch { /* 實務應記錄異常 */ }
        }
    }
}

二、伺服器端完整程式碼

using System.Net.Sockets;
using System.Threading;
using System.IO;
using System.Net;
using System.Windows.Forms;

namespace QQ
{
    public partial class Tcpserver : Form
    {
        int port = 8000;
        private Thread threadRead;
        private TcpListener tcpListen;
        private bool blistener = true;
        private NetworkStream stream;
        private StreamReader read;
        private TcpClient client;
        private delegate void listbox_show(string str);
        listbox_show listboxshow;

        public Tcpserver()
        {
            InitializeComponent();
            listboxshow = new listbox_show(show);
        }

        private void Listen()
        {
            try
            {
                tcpListen = new TcpListener(8000); // 監聽埠 8000
                tcpListen.Start(); // 開始監聽
                client = tcpListen.AcceptTcpClient(); // 同步接受連線
                stream = client.GetStream();
                read = new StreamReader(stream); // 文字讀取器

                while (blistener)
                {
                    string message = read.ReadLine(); // 讀取一行 (阻塞至換行)
                    if (message == "STOP")
                    {
                        tcpListen.Stop();
                        stream.Close();
                        read.Close();
                        threadRead.Abort(); // 強制終止執行緒 (不推薦生產用)
                        return;
                    }
                    string sTime = DateTime.Now.ToShortDateString();
                    listBox1.Invoke(listboxshow, sTime + " " + message);
                }
            }
            catch (System.Security.SecurityException)
            {
                MessageBox.Show("監聽失敗!", "錯誤");
            }
        }

        private void show(string str) { this.listBox1.Items.Add(str); }

        private void button1_Click(object sender, EventArgs e)
        {
            threadRead = new Thread(new ThreadStart(Listen));
            threadRead.Start();
            this.button1.Enabled = false;
        }
    }
}

三、關鍵技術點對比:Socket vs TcpClient/TcpListener

維度Socket (上篇)TcpClient/TcpListener (本篇)
抽象層級底層 Berkeley Socket 封裝應用層高階封裝
資料處理位元組陣列 byte[]串流 NetworkStream + 文字讀寫器
協定支援TCP/UDP/Raw 任意僅 TCP
訊息邊界無 (需自行框架)行導向 ReadLine/WriteLine 內建
編碼處理手動 Encoding.GetBytes/GetStringStreamReader/Writer 內建編碼 (預設 UTF-8)
適用場景高效能、自定義協定、非 TCP快速開發、文字協定、HTTP/POP3/SMTP 類

四、關鍵細節解析

1. 連線建立流程

// 客戶端
tcpclient.Connect("127.0.0.1", 8000); // 阻塞直到連線成功或逾時

// 伺服器端
tcpListen.Start();
client = tcpListen.AcceptTcpClient(); // 阻塞直到有客戶端連線

2. 文字行協定

  • 客戶端:WriteLine 自動附加 Environment.NewLine,Flush 確保立即發送
  • 伺服器端:ReadLine 阻塞讀取直到遇到換行符
  • 優點:天然解決訊息邊界問題
  • 缺點:無法傳輸二進位資料、含換行符的文字

3. 優雅關閉機制

if (message == "STOP") {
    tcpListen.Stop(); // 停止監聽新連線
    stream.Close();   // 關閉串流
    read.Close();     // 關閉讀取器
    threadRead.Abort(); // 強制終止執行緒 (僅示範,生產請用 CancellationToken)
    return;
}

4. 執行緒模型

  • 單一監聽執行緒循序處理:AcceptTcpClient → ReadLine 迴圈
  • 同時間僅能服務一個客戶端
  • 高併發需改用 BeginAcceptTcpClient/EndAcceptTcpClient 或 Task.Run 非同步模式

5. 編碼預設值

  • StreamWriter/StreamReader 預設 Encoding.UTF8 (無 BOM)
  • 跨平台、中文友善,較 Encoding.Default (ANSI) 更推薦

五、常見問題與改進

問題原因改進
單客戶端阻塞單執行緒循序 Accept/Read非同步 Accept + 每客戶端獨立處理執行緒/Task
Thread.Abort() 風險強制終止可能損壞資源狀態使用 CancellationToken + 迴圈檢查優雅退出
無訊息長度限制ReadLine 讀到換行為止加入最大行長度檢查,防止記憶體耗盡
異常吞沒catch { } 空白處理記錄異常日誌,區分暫時性/永久性錯誤

總結

TcpClient/TcpListener + StreamReader/Writer 提供簡潔的文字行導向 TCP 程式設計模型,適合快速原型、簡單協定、教學示範。生產環境高併發場景請採用非同步模式或成熟框架。

本文配套源碼下載
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved