C#制作简单的多人在线即时交流聊天室

这里是 C# 制作简单的多人在线即时交流聊天室的攻略。下面我们将分步骤介绍实现过程。

准备工作

  • 编程环境:Visual Studio 2017 或更高版本。
  • 知识储备:C# .NET 基础知识、Socket 编程、多线程编程、WinForm 界面开发等。

实现步骤

1. 创建 WinForm 应用程序

打开 Visual Studio,创建一个新的 WinForm 应用程序项目。该项目的名字为 ChatRoom。

2. 设计聊天界面

在设计窗口中添加四个控件,以实现多人即时聊天室:

  • 一个 ListBox 控件,用于显示聊天记录。
  • 一个 TextBox 控件,用于输入发送的内容。
  • 一个 Button 控件,用于发送消息。
  • 一个 Label 控件,用于显示在线用户的数量。

3. 实现服务器端

服务器端将使用 C# Socket 编程实现。在解决方案资源管理器中创建一个名为 Server 的新控制台应用程序项目,并添加以下代码:

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;

namespace Server {
    class Program {
        static Hashtable clientsList = new Hashtable();

        static void Main(string[] args) {
            TcpListener serverSocket = new TcpListener(IPAddress.Any, 8080);
            TcpClient clientSocket = default(TcpClient);
            int counter = 0;

            serverSocket.Start();
            Console.WriteLine("Server started...");

            while (true) {
                counter += 1;
                clientSocket = serverSocket.AcceptTcpClient();

                byte[] bytesFrom = new byte[clientSocket.ReceiveBufferSize];
                string dataFromClient = null;

                NetworkStream networkStream = clientSocket.GetStream();
                networkStream.Read(bytesFrom, 0, clientSocket.ReceiveBufferSize);
                dataFromClient = Encoding.Unicode.GetString(bytesFrom);
                dataFromClient = dataFromClient.Substring(0, dataFromClient.IndexOf("$"));

                clientsList.Add(dataFromClient, clientSocket);

                Broadcast(dataFromClient + " joined ", dataFromClient, false);

                Console.WriteLine(dataFromClient + " joined chat room ");
                handleClient client = new handleClient();
                client.startClient(clientSocket, dataFromClient, clientsList);
            }

            clientSocket.Close();
            serverSocket.Stop();

            Console.WriteLine("exit");
            Console.ReadLine();
        }

        public static void Broadcast(string msg, string uName, bool flag) {
            foreach (DictionaryEntry Item in clientsList) {
                TcpClient broadcastSocket;
                broadcastSocket = (TcpClient)Item.Value;
                NetworkStream broadcastStream = broadcastSocket.GetStream();
                Byte[] broadcastBytes = null;

                if (flag) {
                    broadcastBytes = Encoding.Unicode.GetBytes(uName + " says : " + msg);
                } else {
                    broadcastBytes = Encoding.Unicode.GetBytes(msg);
                }

                broadcastStream.Write(broadcastBytes, 0, broadcastBytes.Length);
                broadcastStream.Flush();
            }
        }
    }

    public class handleClient {
        TcpClient clientSocket;
        string clNo;
        Hashtable clientsList;

        public void startClient(TcpClient inClientSocket, string clineNo, Hashtable cList) {
            this.clientSocket = inClientSocket;
            this.clNo = clineNo;
            this.clientsList = cList;
            Thread ctThread = new Thread(doChat);
            ctThread.Start();
        }

        private void doChat() {
            byte[] bytesFrom = new byte[clientSocket.ReceiveBufferSize];
            string dataFromClient = null;

            while (true) {
                try {
                    NetworkStream networkStream = clientSocket.GetStream();
                    networkStream.Read(bytesFrom, 0, clientSocket.ReceiveBufferSize);
                    dataFromClient = Encoding.Unicode.GetString(bytesFrom);
                    dataFromClient = dataFromClient.Substring(0, dataFromClient.IndexOf("$"));

                    Program.Broadcast(dataFromClient, clNo, true);
                } catch {
                    Console.WriteLine(clNo + " disconnected");
                    clientsList.Remove(clNo);
                    Broadcast(clNo + " disconnected", "", false);
                    break;
                }
            }
        }

        public void Broadcast(string msg, string uName, bool flag) {
            byte[] broadcastBytes = null;

            if (flag) {
                broadcastBytes = Encoding.Unicode.GetBytes(uName + " says : " + msg);
            } else {
                broadcastBytes = Encoding.Unicode.GetBytes(msg);
            }

            NetworkStream broadcastStream = clientSocket.GetStream();
            broadcastStream.Write(broadcastBytes, 0, broadcastBytes.Length);
            broadcastStream.Flush();
        }
    }
}

4. 实现客户端

客户端也使用 C# Socket 编程实现。在 ChatRoom 项目中添加一个新的类,名为 ChatClient,并添加以下代码:

using System;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Windows.Forms;

namespace ChatRoom {
    public partial class ChatClient : Form {
        private TcpClient clientSocket = new TcpClient();
        private NetworkStream serverStream = default(NetworkStream);
        private string readData = null;

        public ChatClient() {
            InitializeComponent();
        }

        private void btnConnect_Click(object sender, EventArgs e) {
            readData = "Connecting to chat room server...";
            msg();
            clientSocket.Connect("127.0.0.1", 8080);
            serverStream = clientSocket.GetStream();

            byte[] outStream = Encoding.Unicode.GetBytes(txtUser.Text + "$");
            serverStream.Write(outStream, 0, outStream.Length);
            serverStream.Flush();

            Thread ctThread = new Thread(getMessage);
            ctThread.Start();
        }

        private void btnSend_Click(object sender, EventArgs e) {
            byte[] outStream = Encoding.Unicode.GetBytes(txtMsg.Text + "$");
            serverStream.Write(outStream, 0, outStream.Length);
            serverStream.Flush();
            txtMsg.Text = "";
        }

        private void getMessage() {
            while (true) {
                serverStream = clientSocket.GetStream();
                int buffSize = 0;
                byte[] inStream = new byte[clientSocket.ReceiveBufferSize];
                buffSize = clientSocket.ReceiveBufferSize;
                serverStream.Read(inStream, 0, buffSize);
                string returndata = Encoding.Unicode.GetString(inStream);
                readData = "" + returndata;
                msg();
            }
        }

        private void msg() {
            if (InvokeRequired) {
                this.Invoke(new MethodInvoker(msg));
            } else {
                lstChat.Items.Add(readData);
            }
        }
    }
}

5. 编译并运行聊天室

编译两个项目,启动 ChatRoom 服务器应用程序,并运行 ChatClient 客户端应用程序。在客户端中输入用户名,然后单击“连接”按钮即可加入聊天室。在聊天室中输入消息,然后按下“发送”按钮即可将消息发送给所有在线用户。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C#制作简单的多人在线即时交流聊天室 - Python技术站

(0)
上一篇 2023年6月1日
下一篇 2023年6月1日

相关文章

  • 使用C#开发OPC Server服务器源码解析

    当您准备学习使用C#开发OPC Server服务器时,以下是完整攻略的步骤: 1. 确定OPC Server需要的功能 在开始编写代码前,需要先确定所需的OPC Server功能。例如,是否需要支持多个客户端连接、是否需要支持数据订阅和变化事件等。 2. 选择适合的OPC库 选择一款适合的OPC库很重要,因为它会影响到后续的代码编写和调试。自行编写OPC通信…

    C# 2023年6月6日
    00
  • C# File.WriteAllBytes – 将字节数组写入文件

    C#中的File.WriteAllBytes方法 在C#中,File.WriteAllBytes方法用于将byte数组中的内容写入到指定的文件中。 方法签名 public static void WriteAllBytes(string path, byte[] bytes); 参数说明 path : 需要写入的文件的路径 bytes : 需要写入文件的内容…

    C# 2023年4月19日
    00
  • C#多线程编程中的锁系统(二)

    C#多线程编程中的锁系统(二) 在C#多线程编程中,锁是一种非常常见的同步机制,它可以保证多个线程在访问共享资源时不会发生竞争状况。 本篇文章将详细讲解C#多线程编程中的锁系统,包括锁的类型、使用方法和常见错误等内容。 锁的类型 C#中常见的锁有以下几种类型: 1. Monitor锁 Monitor锁是C#中最基本的锁机制,它是一种基于互斥量(mutex)的…

    C# 2023年5月15日
    00
  • efcore性能调优

    性能调优——EFCore调优 按下硬件、网络不提,我们单表从程序层面对系统的性能进行优化,翻来覆去无外乎三个方面 缓存 异步 sql本片文章,我们针对.net core web项目的ef core框架进行性能优化。 1. EF Core框架已经本地缓存机制memorycache,所以我们访问一个接口,二次访问的性能相比首次会提升一大截 2.尽可能的通过主键查…

    C# 2023年5月5日
    00
  • .Net中的Http请求调用详解(Post与Get)

    在.NET中,可以使用HttpClient类来进行HTTP请求调用。HttpClient类提供了一种简单而灵活的方式来发送HTTP请求并处理响应。下面是在.NET中使用HttpClient类进行HTTP请求调用的完整攻略: 步骤1:创建HttpClient对象 在.NET中,可以使用HttpClient类来发送HTTP请求。要创建HttpClient对象,可…

    C# 2023年5月12日
    00
  • C#中字符串编码处理

    C#中字符串的编码处理需要涉及到多个类和方法。下面将从以下三个方面进行详细说明: 字符集 C#中使用Unicode字符集表示字符串,同时也支持使用ASCII和UTF-8字符集。Unicode字符集定义了每个字符与二进制编码之间的映射关系。ASCII字符集是Unicode字符集的子集,只包含128个常用字符。UTF-8字符集是一种变长编码,可以用1-4个字节表…

    C# 2023年6月7日
    00
  • 详解ASP.NET Razor 语法

    ASP.NET Razor 是一种基于类 HTML 文件的标记语言,它以简单、清晰和易于使用而闻名。本攻略将详细讲解 Razor 语法,以帮助开发人员理解和使用 Razor。 Razor基础 变量 Razor 可以使用 @ 符号来定义变量,比如: @{ var message = "Hello World!"; } 定义完变量之后,就可以…

    C# 2023年5月31日
    00
  • C#扩展方法实例分析

    C#扩展方法实例分析 什么是扩展方法 扩展方法是C#3.0新增的一种语言特性,它可以让我们在不修改原来已经写好的类的情况下,为这些类添加新的方法。扩展方法可以被任何对象调用而不需要继承原有类和实现接口,扩展方法必须声明在静态类中,并且是静态方法,第一个参数必须使用this关键字,这个this关键字指向扩展方法需要操作的对象。 实例分析 示例1 – 扩展方法的…

    C# 2023年6月7日
    00
合作推广
合作推广
分享本页
返回顶部