自己動手設計多人聊天室程式

基礎篇

C# 簡介

開發環境

變數與運算

流程控制

陣列

函數

物件

例外處理

函式庫篇

檔案處理

資料結構

正規表達式

Thread

應用篇

視窗程式

媒體影音

網路程式

遊戲程式

手機程式

資料庫

雲端運算

特殊功能

委派

擴展方法

序列化

LinQ

WPF

網路資源

教學影片

投影片

教學文章

軟體下載

考題解答

101習題

專案程式下載:ChattingRoom.zip

// ---------------------------------------------------------------
// 共有五個程式檔案
//
//  程式檔 : ChatLib.cs
//  程式檔 : ChattServer.cs
//  程式檔 : WinChatClient.cs
//  程式檔 : FormChatClient.cs
//  程式檔 : FormChatClient.Designer.cs
//
// 編譯方式 : 
//    步驟 1 : csc ChatServer.cs ChatLib.cs
//             會產生 ChatServer.exe 檔
//
//    步驟 2 : csc WinChatClient.cs FormChatClient.cs FormChatClient.Designer.cs ChatLib.cs
//             會產生 WinChatClient.exe 檔
//     
// 執行方式 : 
//    步驟 1 : 執行 ChatServer.exe
//    步驟 2 : 執行 WinChatClient.exe (使用者 1)
//    步驟 3 : 執行 WinChatClient.exe (使用者 2)
//
// 如此,兩個 WinChatClient.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();
        }
    }
}
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License