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

Socket 程式設計實戰 (三):TcpClient/TcpListener 完整範例

     編輯:關於.NET

文章導讀

本文提供基於 System.Net.Sockets.Socket 類別的完整客戶端/伺服器端程式碼範例,展示同步阻塞式 TCP 通訊基礎模式。適合網路程式設計入門者參考。

核心知識點

  • Socket 建立、連線、傳送、關閉完整流程
  • 伺服器端多執行緒監聽與非同步 UI 更新
  • IPAddress、IPEndPoint、Encoding 關鍵類別運用
  • 委派跨執行緒更新 WinForms 控制項

一、客戶端完整程式碼

using System.Windows.Forms;
using System.Net;
using System.Threading;
using System.Net.Sockets;
using System.Text; // Encoding 命名空間

namespace QQ
{
    public partial class Socketclient : Form
    {
        public Socketclient() { InitializeComponent(); }

        private void button1_Click(object sender, EventArgs e)
        {
            string str = this.textBox1.Text.ToString();
            BeginSend(str);
        }

        private void BeginSend(string str)
        {
            IPAddress serverIp = IPAddress.Parse("127.0.0.1");
            IPEndPoint iep = new IPEndPoint(serverIp, 8000);
            byte[] byteMessage;
            
            // 建立 TCP Socket
            Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            socket.Connect(iep); // 同步阻塞連線
            
            byteMessage = Encoding.ASCII.GetBytes(str); // 字串轉位元組陣列
            socket.Send(byteMessage); // 同步阻塞傳送
            
            socket.Shutdown(SocketShutdown.Both); // 關閉雙向傳輸
            socket.Close(); // 釋放資源
        }
    }
}

二、伺服器端完整程式碼

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

namespace QQ
{
    public partial class SocketServer : Form
    {
        Thread myThread;
        Socket socket;
        private delegate void listbox_show(string str);
        listbox_show listboxshow;

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

        private IPAddress GetServerIp()
        {
            IPHostEntry ieh = Dns.GetHostEntry(Dns.GetHostName()); // 取得本機 IP
            return ieh.AddressList[0];
        }

        private void BeginListen()
        {
            IPAddress ip1 = GetServerIp();
            IPEndPoint iep = new IPEndPoint(ip1, 8000);
            socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            socket.Bind(iep); // 綁定本機端點
            byte[] byteMessage = new byte[1000];

            while (true)
            {
                try
                {
                    socket.Listen(5); // 開始監聽,佇列長度 5
                    Socket clientSocket = socket.Accept(); // 同步阻塞等待連線
                    clientSocket.Receive(byteMessage); // 同步阻塞接收資料
                    
                    string sTime = DateTime.Now.ToShortDateString();
                    string msg = sTime + ": " + "Message from: ";
                    msg += clientSocket.RemoteEndPoint.ToString() + Encoding.Default.GetString(byteMessage);
                    
                    // 跨執行緒更新 UI:Invoke 委派
                    this.listBox1.Invoke(listboxshow, msg);
                }
                catch (System.Exception ex)
                {
                    MessageBox.Show(ex.Message.ToString());
                }
            }
        }

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

        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                myThread = new Thread(new ThreadStart(BeginListen));
                myThread.Start(); // 背景執行緒啟動監聽
                this.button1.Enabled = false;
            }
            catch (System.Exception er)
            {
                MessageBox.Show(er.Message, "完成", MessageBoxButtons.OK, MessageBoxIcon.Stop);
            }
        }
    }
}

三、關鍵技術點解析

1. Socket 三要素

參數值說明
AddressFamilyInterNetworkIPv4 網際網路協定
SocketTypeStream串流式、可靠、雙向 (TCP)
ProtocolTypeTcp傳輸控制協定

2. 同步阻塞模式特徵

  • Connect()、Send()、Accept()、Receive() 皆為同步阻塞呼叫
  • 執行緒在操作完成前被佔用,無法處理其他工作
  • 簡單直觀,適合低併發、教學示範

3. 伺服器端多執行緒架構

  • 主執行緒:UI 回應、啟動監聽執行緒
  • 監聽執行緒:while(true) 迴圈 Accept() → Receive() → Invoke() 更新 UI
  • 缺陷:單一監聽執行緒只能循序處理一個客戶端,高併發下會阻塞

4. 跨執行緒 UI 更新

// 定義委派
private delegate void listbox_show(string str);
listbox_show listboxshow = new listbox_show(show);

// 背景執行緒中呼叫
this.listBox1.Invoke(listboxshow, msg);

// UI 執行緒實際執行
private void show(string str) { this.listBox1.Items.Add(str); }

原則:Windows Forms 控制項只能在建立它們的執行緒 (UI 執行緒) 存取,跨執行緒必須用 Control.Invoke/BeginInvoke。

5. 編碼一致性

  • 客戶端:Encoding.ASCII.GetBytes
  • 伺服器端:Encoding.Default.GetString (系統預設編碼,通常為 ANSI)
  • 建議:雙端統一使用 Encoding.UTF8 避免中文亂碼

四、改進方向 (進階主題)

  1. 非同步 Socket:BeginConnect/EndConnect, BeginSend/EndSend, BeginAccept/EndAccept, BeginReceive/EndReceive — 不阻塞執行緒,支援高併發
  2. SocketAsyncEventArgs:.NET 3.5+ 高效能非同步模式,避免物件分配
  3. TcpClient/TcpListener:更高層封裝,簡化 NetworkStream 讀寫
  4. 長度前綴/訊息框架:解決 TCP 黏包/拆包問題
  5. 心跳/重連/優雅關閉:生產級健壯性保障

總結

本範例展示最基礎的同步阻塞 Socket 程式設計模式。實務開發中,請根據併發需求選擇非同步模式或成熟網路框架 (如 DotNetty, SignalR, gRPC)。

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