close
雙向P2P聊天程式 

簡介

聊天程式是學習網路程式設計很好的入門題目之一,在本文中,我們將示範如何用 C# 的 Socket 函式庫設計一個網路聊天程式。以下是這個程式的執行時的一個畫面,讀者可以看到我們在兩個命令列視窗中執行同一個 ChatBox 程式,左上角是 Server 程式,右下角是 Client 程式。

ChatBox.jpg

在上圖中,Client 可以傳送訊息給 Server ,而 Server 也可傳送訊息給 Client,由於雙方在這個傳送接收的動作上幾乎是相同的,因此在寫程式時就將這些動作封裝後共用,可以讓程式更為精簡,這就是 P2P 架構的程式。

當然,這個程式也可以放在兩台不同的電腦上執行,其結果將與上述結果類似,只是無法同時在一台電腦上看到輸入與輸出的結果而已。

原始程式碼

以下是上述雙向聊天程式 ChatBox 的原始程式碼,其中的 TcpListener 程式是 Client-Server 雙方所共用的部分,因此獨立出來變成一個類別,並且分別在 Client 與 Server 主程式當中都用 new TcpListener() 的方式呼叫。此時雙方都會建立一個寫入迴圈 (outLoop) 與讀取回圈 (inLoop),寫入迴圈不斷等待鍵盤的輸入,並在有輸入時將訊息傳遞給對方。而讀取回圈則是不斷接收對方所傳來的訊息並顯示在螢幕上。

using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Threading;
class ChatBox
{
    int port = 20;
    public static void Main(String[] args)
    {
        ChatBox chatBox = new ChatBox();
        if (args.Length == 0)
         chatBox.ServerMain();
        else
         chatBox.ClientMain(args[0]);
    }
    public void ServerMain()
    {
        IPEndPoint ipep = new IPEndPoint(IPAddress.Any, port);
        Socket newsock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        newsock.Bind(ipep);
        newsock.Listen(10);
        Socket client = newsock.Accept();
        new TcpListener(client); // create a new thread and then receive message.
        newsock.Close();
    }
    public void ClientMain(String ip)
    {
        IPEndPoint ipep = new IPEndPoint(IPAddress.Parse(ip), port);
        Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        server.Connect(ipep);
        new TcpListener(server);
        server.Shutdown(SocketShutdown.Both);
        server.Close();
    }
}
public class TcpListener
{
    Socket socket;
    Thread inThread, outThread;
    NetworkStream stream;
    StreamReader reader;
    StreamWriter writer;
    public TcpListener(Socket s)
    {
        socket = s;
        stream = new NetworkStream(s);
        reader = new StreamReader(stream);
        writer = new StreamWriter(stream);
        inThread = new Thread(new ThreadStart(inLoop));
        inThread.Start();
        outThread = new Thread(new ThreadStart(outLoop));
        outThread.Start();
        inThread.Join(); // 等待 inThread 執行續完成,才離開此函數。 
        // (注意、按照 inLoop 的邏輯,這個函數永遠不會跳出,因為 inLoop 是個無窮迴圈)。
    } 
    public void inLoop()
    {
        while (true)
        {
         String line = reader.ReadLine();
         Console.WriteLine("收到:" + line);
        }
    }
    public void outLoop()
    {
        while (true)
        {
         String line = Console.ReadLine();
         writer.WriteLine(line);
         writer.Flush();
        }
    }
}
	

陳鍾誠 (2010年06月15日),(網頁標題) C# :雙向P2P聊天程式,(網站標題) 免費電子書:C# 程式設計,2010年06月15日,取自 http://cs0.wikidot.com/chatbox ,網頁修改第 2 版。

arrow
arrow

    Johnson峰 發表在 痞客邦 留言(0) 人氣()