陳鍾誠 | 教材 | 程式 | 文章 | 留言版


自己動手設計多人聊天室程式 - 使用 C#


  • 程式下載:ChattingRoom.zip

  • // ---------------------------------------------------------------
    // 共有5個程式檔案
    //
    //  程式檔 : ChatLib.cs
    //  程式檔 : ChattingServer.cs
    //  程式檔 : FormChatClient.cs
    //  程式檔 : FormChatClient.Designer.cs
    //  程式檔 : WinChatClient.cs
    //
    // 編譯方式 : 
    //    步驟 1 : csc ChattingServer.cs ChatLib.cs
    //             會產生 ChattingServer.exe 檔
    //
    //    步驟 2 : csc FormChatClient.cs FormChatClilent.Designer.cs ChatLib.cs
    //             會產生 FormChatClient.exe 檔
    //     
    // 執行方式 : 
    //    步驟 1 : 執行 ChattingServer.exe
    //    步驟 2 : 執行 FormChatClient.exe
    //    步驟 3 : 執行 FormChatClient.exe
    //
    // 如此,兩個 FormChatClient.exe 的視窗間即可透過本機聊天
    // ---------------------------------------------------------------
    

    // ------------------------- ChatLib.cs --------------------------
    using System;
    using System.Net;
    using System.Net.Sockets;
    using System.IO;
    using System.Threading;
    
    namespace ChattingRoom { public class ChatSetting { public static String serverIp = "192.168.100.172"; public static int port = 3766; }
    public delegate String StrHandler(String str);
    public class ChatSocket { public Socket socket; public NetworkStream stream; public StreamReader reader; public StreamWriter writer; public StrHandler inHandler; public EndPoint remoteEndPoint; public bool isDead = false;
    public ChatSocket(Socket s) { socket = s; stream = new NetworkStream(s); reader = new StreamReader(stream); writer = new StreamWriter(stream); remoteEndPoint = socket.RemoteEndPoint; }
    public String receive() { return reader.ReadLine(); }
    public ChatSocket send(String line) { writer.WriteLine(line); writer.Flush(); return this; }
    public static ChatSocket connect(String ip) { IPEndPoint ipep = new IPEndPoint(IPAddress.Parse(ip), ChatSetting.port);
    Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); socket.Connect(ipep); return new ChatSocket(socket); }
    public Thread newListener(StrHandler pHandler) { inHandler = pHandler;
    Thread listenThread = new Thread(new ThreadStart(listen)); listenThread.Start(); return listenThread; }
    public void listen() { try { while (true) { String line = receive(); inHandler(line); } } catch (Exception ex) { isDead = true; Console.WriteLine(ex.Message); } } } }

    // ------------------------- ChattingServer.cs -------------------
    using System;
    using System.Net;
    using System.Net.Sockets;
    using System.IO;
    using System.Threading;
    using System.Collections.Generic;
    
    namespace ChattingRoom { public class ChatServer { List<ChatSocket> clientList = new List<ChatSocket>();
    public static void Main(String[] args) { ChatServer chatServer = new ChatServer(); chatServer.run(); }
    public void run() { IPEndPoint ipep = new IPEndPoint(IPAddress.Any, ChatSetting.port);
    Socket newsock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    newsock.Bind(ipep); newsock.Listen(10);
    while (true) { Socket socket = newsock.Accept(); Console.WriteLine("接受一個新連線!"); ChatSocket client = new ChatSocket(socket); try { clientList.Add(client); client.newListener(processMsgComeIn); } catch { } // clientList.Remove(client); } // newsock.Close(); }
    public String processMsgComeIn(String msg) { Console.WriteLine("收到訊息:"+msg); broadCast(msg); return "OK"; }
    public void broadCast(String msg) { Console.WriteLine("廣播訊息給 " + msg+" 線上使用者共"+clientList.Count+"個人!"); foreach (ChatSocket client in clientList) { if (!client.isDead) { Console.WriteLine("Send to "+client.remoteEndPoint.ToString()+":"+msg); client.send(msg); } } } } }

    // ------------------------- FormChatClient.cs -------------------
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;
    
    namespace ChattingRoom { public partial class FormChatClient : Form { ChatSocket client; StrHandler msgHandler;
    public FormChatClient() { InitializeComponent();
    msgHandler = this.addMsg; }
    private void buttonSend_Click(object sender, EventArgs e) { sendMsg(); } private void textBoxMsg_KeyPress(object sender, KeyPressEventArgs e) { if (e.KeyChar == '\r') sendMsg(); }
    public String user() { return textBoxUser.Text.Trim(); }
    public String msg() { return textBoxMsg.Text; }
    public void sendMsg() { if (user().Length == 0) { MessageBox.Show("請輸入使用者名稱!"); return; } if (client == null) { client = ChatSocket.connect(ChatSetting.serverIp); client.newListener(processMsgComeIn); client.send(user() + " : 新使用者進入!"); textBoxUser.Enabled = false; } if (msg().Length > 0) { client.send(user()+" : "+msg()); textBoxMsg.Text = ""; } }
    public String processMsgComeIn(String msg) { this.Invoke(msgHandler, new Object[] { msg }); return "OK"; }
    public String addMsg(String msg) { richTextBoxBoard.AppendText(msg + "\n"); return "OK"; } } }

    // ------------------------- FormChatClient.Designer.cs ----------
    namespace ChattingRoom
    {
        partial class FormChatClient
        {
            /// <summary>
            /// 設計工具所需的變數。
            /// </summary>
            private System.ComponentModel.IContainer components = null;
    
    /// <summary> /// 清除任何使用中的資源。 /// </summary> /// <param name="disposing">如果應該公開 Managed 資源則為 true,否則為 false。</param> protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); }
    #region Windows Form 設計工具產生的程式碼
    /// <summary> /// 此為設計工具支援所需的方法 - 請勿使用程式碼編輯器修改這個方法的內容。 /// /// </summary> private void InitializeComponent() { this.panelInput = new System.Windows.Forms.Panel(); this.labelSaid = new System.Windows.Forms.Label(); this.textBoxUser = new System.Windows.Forms.TextBox(); this.textBoxMsg = new System.Windows.Forms.TextBox(); this.buttonSend = new System.Windows.Forms.Button(); this.panelPadding1 = new System.Windows.Forms.Panel(); this.panelMsg = new System.Windows.Forms.Panel(); this.richTextBoxBoard = new System.Windows.Forms.RichTextBox(); this.panelInput.SuspendLayout(); this.panelMsg.SuspendLayout(); this.SuspendLayout(); // // panelInput // this.panelInput.Controls.Add(this.labelSaid); this.panelInput.Controls.Add(this.textBoxUser); this.panelInput.Controls.Add(this.textBoxMsg); this.panelInput.Controls.Add(this.buttonSend); this.panelInput.Controls.Add(this.panelPadding1); this.panelInput.Dock = System.Windows.Forms.DockStyle.Bottom; this.panelInput.Location = new System.Drawing.Point(0, 283); this.panelInput.Name = "panelInput"; this.panelInput.Size = new System.Drawing.Size(494, 64); this.panelInput.TabIndex = 0; // // labelSaid // this.labelSaid.AutoSize = true; this.labelSaid.Font = new System.Drawing.Font("DFKai-SB", 15.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(136))); this.labelSaid.Location = new System.Drawing.Point(94, 17); this.labelSaid.Name = "labelSaid"; this.labelSaid.Size = new System.Drawing.Size(54, 21); this.labelSaid.TabIndex = 4; this.labelSaid.Text = "說:"; // // textBoxUser // this.textBoxUser.Location = new System.Drawing.Point(3, 17); this.textBoxUser.Name = "textBoxUser"; this.textBoxUser.Size = new System.Drawing.Size(88, 22); this.textBoxUser.TabIndex = 3; // // textBoxMsg // this.textBoxMsg.Location = new System.Drawing.Point(154, 17); this.textBoxMsg.Name = "textBoxMsg"; this.textBoxMsg.Size = new System.Drawing.Size(250, 22); this.textBoxMsg.TabIndex = 2; this.textBoxMsg.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.textBoxMsg_KeyPress); // // buttonSend // this.buttonSend.Location = new System.Drawing.Point(410, 14); this.buttonSend.Name = "buttonSend"; this.buttonSend.Size = new System.Drawing.Size(81, 28); this.buttonSend.TabIndex = 1; this.buttonSend.Text = "送出"; this.buttonSend.UseVisualStyleBackColor = true; this.buttonSend.Click += new System.EventHandler(this.buttonSend_Click); // // panelPadding1 // this.panelPadding1.Dock = System.Windows.Forms.DockStyle.Bottom; this.panelPadding1.Location = new System.Drawing.Point(0, 48); this.panelPadding1.Name = "panelPadding1"; this.panelPadding1.Size = new System.Drawing.Size(494, 16); this.panelPadding1.TabIndex = 0; // // panelMsg // this.panelMsg.Controls.Add(this.richTextBoxBoard); this.panelMsg.Dock = System.Windows.Forms.DockStyle.Fill; this.panelMsg.Location = new System.Drawing.Point(0, 0); this.panelMsg.Name = "panelMsg"; this.panelMsg.Size = new System.Drawing.Size(494, 283); this.panelMsg.TabIndex = 1; // // richTextBoxBoard // this.richTextBoxBoard.Dock = System.Windows.Forms.DockStyle.Fill; this.richTextBoxBoard.Location = new System.Drawing.Point(0, 0); this.richTextBoxBoard.Name = "richTextBoxBoard"; this.richTextBoxBoard.Size = new System.Drawing.Size(494, 283); this.richTextBoxBoard.TabIndex = 0; this.richTextBoxBoard.Text = ""; // // FormChatClient // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(494, 347); this.Controls.Add(this.panelMsg); this.Controls.Add(this.panelInput); this.Name = "FormChatClient"; this.Text = "C# 聊天室"; this.panelInput.ResumeLayout(false); this.panelInput.PerformLayout(); this.panelMsg.ResumeLayout(false); this.ResumeLayout(false);
    }
    #endregion
    private System.Windows.Forms.Panel panelInput; private System.Windows.Forms.Panel panelMsg; private System.Windows.Forms.TextBox textBoxMsg; private System.Windows.Forms.Button buttonSend; private System.Windows.Forms.Panel panelPadding1; private System.Windows.Forms.RichTextBox richTextBoxBoard; private System.Windows.Forms.Label labelSaid; private System.Windows.Forms.TextBox textBoxUser; } }

    using System;
    using System.Collections.Generic;
    using System.Windows.Forms;
    
    namespace ChattingRoom { static class Program { /// <summary> /// 應用程式的主要進入點。 /// </summary> [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new FormChatClient()); Application.Exit(); } } }




    作者:陳鍾誠 E-mail:ccc@kmit.edu.tw
    Creative Commons License

    本著作係採用創用 CC 「姓名標示─相同方式分享 2.5 台灣版」授權條款釋出。

    大學課程網 | 手機入口網