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

C# 網路程式設計基礎:TCP 通訊、Socket 概念與聊天程式架構全解析 (上)

     編輯:關於C#

前言

本系列文章旨在淺顯易懂地介紹 C# 網路程式設計的核心基礎知識。筆者功力有限,僅提供入門級指引,若需深入研究,建議參考專業書籍。本文為系列首篇,重點闡述基於 Socket 的網路程式設計基本概念,涵蓋 TCP 協定、Socket 運作原理、三種主流聊天程式開發模式,以及兩項核心操作:連接埠監聽與遠端伺服器連線。後續文章將逐步實作字串傳輸、非同步通訊、檔案收發,最終完成一個具備線上聊天與檔案傳輸功能的綜合聊天程式。

網路程式設計核心概念

1. 面向連線的傳輸協定:TCP

TCP 屬於傳輸層協定,特性為「面向連線」、「全雙工」、「點對點」以及「可靠傳輸」。所謂面向連線,意指雙方進程必須經過三向交握確認連線成功,才能傳輸實際資料。全雙工意味著連線建立後,資料可雙向流動;點對點則限定一條 TCP 連線僅連結兩個端點;可靠傳輸保證資料有序、無誤到達。

2. Socket:應用層與傳輸層的橋樑

應用程式位於應用層,欲使用 TCP 服務,需透過 Socket 介面。Socket 如同郵筒投遞口:應用層負責撰寫、封裝資料(信件),投入 Socket 後,後續路由、傳輸等細節由底層協定處理,開發者無需關心。Socket 核心包含本地端點(本機 IP 與連接埠)與遠端端點(對方 IP 與連接埠)資訊。

3. 連接埠:識別應用程式的編號

一台電腦同時運行多個網路程式,遠端主機需透過連接埠號辨識目標程式。恰似電話號碼(IP)加分機號(Port),唯有正確組合才能精準送達。

4. .NET 封裝類別:TcpListener 與 TcpClient

.NET 提供 TcpListener 與 TcpClient 封裝底層 Socket,簡化開發。TcpListener 專責監聽連線請求,TcpClient 則處理資料收發流。監聽端接受請求後,會產生一個 TcpClient 實例進行實際通訊,而 TcpListener 持續保持監聽狀態,可同時服務多個用戶端。

網路聊天程式的三種架構模式

模式一:完全點對點(P2P)

每部電腦同時扮演用戶端與伺服器,需自行監聽連接埠。新節點上線時透過 UDP 廣播宣告存在,其他節點回應確認。缺點是廣播機制複雜,且隨節點增加管理困難。

模式二:中央伺服器協助直連

引入專用伺服器處理節點上線廣播。節點啟動先連線伺服器,伺服器將新節點資訊轉發給所有在線節點,後續節點間直接建立 TCP 連線通訊。各節點仍需維持監聽狀態。

模式三:中央伺服器轉發(推薦)

所有訊息經由伺服器中轉:節點 A → 伺服器 → 節點 B。優點在於節點無需監聽連接埠,僅伺服器監聽即可,大幅簡化開發。大型檔案傳輸時可臨時建立點對點連線。伺服器亦可快取離線訊息,實現離線推播。

本系列採用模式三作為最終實作架構。

基本操作實作

1. 伺服端監聽連接埠

建立主控台專案 ServerConsole,使用 TcpListener 於本機 IP(127.0.0.1)與連接埠 8500 開始監聽:

using System.Net;
using System.Net.Sockets;

class Server {
    static void Main(string[] args) {
        Console.WriteLine("Server is running ...");
        IPAddress ip = new IPAddress(new byte[] { 127, 0, 0, 1 });
        TcpListener listener = new TcpListener(ip, 8500);
        listener.Start();
        Console.WriteLine("Start Listening ...");
        Console.WriteLine("\n\n按 'Q' 鍵退出。");
        ConsoleKey key;
        do {
            key = Console.ReadKey(true).Key;
        } while (key != ConsoleKey.Q);
    }
}

執行後可透過 netstat -a 確認連接埠 8500 狀態為 LISTENING。程式必須阻塞(如 Console.ReadKey)避免提前結束導致連線中斷。

2. 用戶端連線伺服器

2.1 單一用戶端連線

建立 ClientConsole 專案,使用 TcpClient.Connect 同步連線:

class Client {
    static void Main(string[] args) {
        Console.WriteLine("Client Running ...");
        TcpClient client = new TcpClient();
        try {
            client.Connect("localhost", 8500);
        } catch (Exception ex) {
            Console.WriteLine(ex.Message);
            return;
        }
        Console.WriteLine("Server Connected!{0} --> {1}",
            client.Client.LocalEndPoint, client.Client.RemoteEndPoint);
        // 按 Q 退出邏輯省略
    }
}

連線成功後,用戶端會獲得一個隨機指派的本地連接埠(如 4761),伺服器端 8500 維持監聽狀態,可接受多連線。

2.2 多用戶端連線

迴圈建立多個 TcpClient 實例並各自呼叫 Connect 即可實現多連線。每個實例對應獨立 Socket 與連接埠,伺服器端 8500 持續監聽,netstat -a 可見多組 ESTABLISHED 連線。

3. 伺服端接受用戶端連線

3.1 接受單一連線

呼叫 listener.AcceptTcpClient() 同步阻塞等待連線,獲得 TcpClient 實例後可讀取遠端端點資訊。

3.2 接受多重連線

將 AcceptTcpClient() 置於 while(true) 迴圈中,每當有新連線即處理並印出資訊。雖為無限迴圈,但方法阻塞特性使其大多數時間處於等待狀態,不會耗盡資源,亦符合伺服器長期運行特性。

本篇結束,下一篇將探討伺服端與用戶端間的資料收發機制。

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