TCP 網路程式設計

基礎篇

C# 簡介

開發環境

變數與運算

流程控制

陣列

函數

物件

例外處理

函式庫篇

檔案處理

資料結構

正規表達式

Thread

應用篇

視窗程式

媒體影音

網路程式

遊戲程式

手機程式

資料庫

雲端運算

特殊功能

委派

擴展方法

序列化

LinQ

WPF

網路資源

教學影片

投影片

教學文章

軟體下載

考題解答

101習題

簡介

TCP 是一個連線導向的網路傳輸協定,程式通常在斷線之前會一直記住這個連線。在我們使用 Socket 函式庫設計 TCP 網路程式時,通常會讓一個 Thread 負責處理一條連線,這樣可以讓問題變得較為單純,因為不需要用表格去記住連線。

所以,在學習 TCP 程式設計之前,我們有必要先複習一下 Thread (台灣稱為執行緒、中國大陸稱為線程) 的程式設計方式,若讀者對 Thread 尚不熟悉,請讀者先看完下列兩篇文章後再回到此處閱讀。

  1. Thread 的概念
  2. C#與 Thread
  3. C#與死結 (DeadLock)

TCP 的程式架構

TCP 客戶端的通常在連上伺服端後,就會用一個迴圈透過 Socket.send 函數傳送訊息,以下是一個典型的 TCP 客戶端程式。

客戶端:Client

        IPEndPoint ip = new IPEndPoint(IPAddress.Parse(address), port);
        Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        server.Connect(ip);
        ...
        while(true) {
            ...
            server.Send(data);
            ...
        }
        ...
        server.Shutdown(SocketShutdown.Both);
        server.Close();

TCP 伺服端通常較為複雜,首先在利用 Socket 中的 bind() 函數佔用特定的 port 之後,會再進入一個無窮迴圈,在迴圈中利用 socket.Accept() 接受客戶端的連線,此時會產生一個新的 Socket 物件。通常,我們會建立一個新的 Thread 去處理這個連線,因此在下列程式中,我們建立了 TcpListener 這個物件,以便讓一個 Listener 處理一個 Socket 連線。

伺服端:Server

public class TcpServer
{
    public static void Main()
    {
        IPEndPoint ip = new IPEndPoint(IPAddress.Any, port);
        Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        socket.Bind(ip);
        socket.Listen(10);
        while(true)
        {
            Socket client = socket.Accept();
            TcpListener listener = new TcpListener(client); // 建立 Listener 物件處理這個連線。
            Thread thread = new Thread(new ThreadStart(listener.run)); // 建立 listener.run 的 Thread。
            thread.Start(); // 啟動 Thread
            ...
        }
         ...
    }
}

public class TcpListener {
    Socket socket;

    public TcpListener(Socket s)  { socket = s; }

    public void run() { // Thread 的主要函數
        while (true)  {
            ...
            byte[] data = new byte[1024];
            int recv = socket.Receive(data); // 接收資料
            ...
        }
        socket.Close();
    }
}

結語

以上就是一個典型的 TCP 程式架構,該架構包含了『客戶端-伺服端』兩個部分,客戶端透過 Socket.send 傳送訊息,而伺服端則會針對每一個連線,建立新的 Thread ,以便處理連線的互動關係。這種架構對 TCP 而言是較為簡單的,有幾個連線就建立幾個 Thread。由於這種架構不需要用表格記住連線,因此簡化了伺服端的管理,讓程式設計更為容易。

在理解了這個架構後,您可以看看真實的程式範例,以下是筆者所撰寫的幾個相關程式,敬請參考。

  1. TCP : 單向的訊息傳遞程式
  2. TCP : 雙向的P2P聊天程式
  3. TCP : 多人聊天室
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License