c#多线程网络聊天程序代码分享(服务器端和客户端)

C#多线程网络聊天程序代码分享(服务器端和客户端)

介绍

本文所分享的是使用C#编写的多线程网络聊天程序的源代码,包括服务器端和客户端代码。网络聊天程序可以实现在不同计算机之间进行即时聊天的功能,多线程可以提升程序的并发性和性能,同时使用C#编写可以大大简化代码编写过程。

实现流程

  1. 服务器端程序编写

服务器端程序的主要作用是接受用户请求,并与客户端进行通讯。以下是服务器端代码的主要实现过程:

  • 创建Socket对象,并指定所使用的协议和通信类型。
Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  • 绑定IP地址和端口号,即指定服务器端进行监听的网络地址。
IPEndPoint serverIpEndPoint = new IPEndPoint(IPAddress.Parse("服务器IP地址"), 8888);
serverSocket.Bind(serverIpEndPoint);
  • 开始监听客户端连接请求。
serverSocket.Listen(5);
  • 使用无限循环进行接收客户端请求,并在有客户端接入时创建一个新的线程进行处理。
while (true)
{
    Socket clientSocket = serverSocket.Accept();
    //使用新线程处理客户端请求
    Thread thread = new Thread(ClientThreadProc);
    thread.Start(clientSocket);
}
  • 在新线程中处理客户端的请求,包括接收客户端的消息和向客户端发送消息。
private void ClientThreadProc(object param)
{
    Socket clientSocket = (Socket)param;
    //接收来自客户端的消息
    byte[] buffer = new byte[1024 * 1024];
    int count = clientSocket.Receive(buffer);
    string msg = Encoding.UTF8.GetString(buffer, 0, count);
    //向客户端发送消息
    clientSocket.Send(Encoding.UTF8.GetBytes("收到了你的消息:" + msg));
    clientSocket.Close();
}
  1. 客户端程序编写

客户端程序的主要作用是与服务器端进行通讯,并向服务器端发送消息。以下是客户端代码的主要实现过程:

  • 创建Socket对象,并连接到服务器端。
Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint serverIpEndPoint = new IPEndPoint(IPAddress.Parse("服务器IP地址"), 8888);
clientSocket.Connect(serverIpEndPoint);
  • 向服务器端发送消息。
string msg = "你好,服务器!";
clientSocket.Send(Encoding.UTF8.GetBytes(msg));
  • 接收来自服务器端的消息。
byte[] buffer = new byte[1024 * 1024];
int count = clientSocket.Receive(buffer);
string msg = Encoding.UTF8.GetString(buffer, 0, count);
  • 关闭Socket对象。
clientSocket.Close();

示例说明

以下是基于上述代码实现的多线程网络聊天程序的两个示例说明。

示例1:单一服务器

假设有1台服务器和2个客户端,可以使用以下代码实现多线程网络聊天:

  • 服务器端代码:
public class Server
{
    private Socket serverSocket;

    public void Start()
    {
        serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        IPEndPoint serverIpEndPoint = new IPEndPoint(IPAddress.Parse("服务器IP地址"), 8888);
        serverSocket.Bind(serverIpEndPoint);
        serverSocket.Listen(5);

        while (true)
        {
            Socket clientSocket = serverSocket.Accept();
            Thread thread = new Thread(ClientThreadProc);
            thread.Start(clientSocket);
        }
    }

    private void ClientThreadProc(object param)
    {
        Socket clientSocket = (Socket)param;
        byte[] buffer = new byte[1024 * 1024];
        int count = clientSocket.Receive(buffer);
        string msg = Encoding.UTF8.GetString(buffer, 0, count);
        Console.WriteLine("服务器接收到来自客户端的消息:" + msg);
        clientSocket.Send(Encoding.UTF8.GetBytes("服务器已收到你的消息:" + msg));
        clientSocket.Close();
    }
}
  • 客户端代码:
public class Client
{
    private Socket clientSocket;

    public void SendMessage(string msg)
    {
        clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        IPEndPoint serverIpEndPoint = new IPEndPoint(IPAddress.Parse("服务器IP地址"), 8888);
        clientSocket.Connect(serverIpEndPoint);
        clientSocket.Send(Encoding.UTF8.GetBytes(msg));

        byte[] buffer = new byte[1024 * 1024];
        int count = clientSocket.Receive(buffer);
        string responseMsg = Encoding.UTF8.GetString(buffer, 0, count);
        Console.WriteLine("客户端接收到来自服务器的消息:" + responseMsg);

        clientSocket.Close();
    }
}
  • 测试代码:
static void Main(string[] args)
{
    Server server = new Server();
    new Thread(server.Start).Start();

    Client client1 = new Client();
    new Thread(() => client1.SendMessage("你好,服务器!")).Start();

    Client client2 = new Client();
    new Thread(() => client2.SendMessage("来自客户端2的消息!")).Start();

    Console.ReadLine();
}

执行以上代码后,在服务器端的控制台输出如下:

服务器接收到来自客户端的消息:你好,服务器!
服务器接收到来自客户端的消息:来自客户端2的消息!

客户端1的控制台输出如下:

客户端接收到来自服务器的消息:服务器已收到你的消息:你好,服务器!

客户端2的控制台输出如下:

客户端接收到来自服务器的消息:服务器已收到你的消息:来自客户端2的消息!

可以看出,客户端发送的消息已经被服务器端接收,并向每个客户端发送响应消息。

示例2:多服务器

假设有2台服务器和2个客户端,可以使用以下代码实现多线程网络聊天:

  • 服务器1代码:
public class Server1
{
    private Socket serverSocket;

    public void Start()
    {            
        serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        IPEndPoint serverIpEndPoint = new IPEndPoint(IPAddress.Parse("服务器1IP地址"), 8888);
        serverSocket.Bind(serverIpEndPoint);
        serverSocket.Listen(5);

        while (true)
        {
            Socket clientSocket = serverSocket.Accept();
            Thread thread = new Thread(() => ClientThreadProc1(clientSocket));
            thread.Start();
        }
    }

    private void ClientThreadProc1(Socket clientSocket)
    {
        byte[] buffer = new byte[1024 * 1024];
        int count = clientSocket.Receive(buffer);
        string msg = Encoding.UTF8.GetString(buffer, 0, count);
        Console.WriteLine("服务器1接收到来自客户端的消息:" + msg);

        Socket server2Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        IPEndPoint server2IpEndPoint = new IPEndPoint(IPAddress.Parse("服务器2IP地址"), 8889);
        server2Socket.Connect(server2IpEndPoint);

        server2Socket.Send(Encoding.UTF8.GetBytes(msg));
        buffer = new byte[1024 * 1024];
        count = server2Socket.Receive(buffer);
        string responseMsg = Encoding.UTF8.GetString(buffer, 0, count);
        Console.WriteLine("服务器1接收到来自服务器2的响应消息:" + responseMsg);

        server2Socket.Close();
        clientSocket.Send(Encoding.UTF8.GetBytes(responseMsg));
        clientSocket.Close();
    }
}
  • 服务器2代码:
public class Server2
{
    private Socket serverSocket;

    public void Start()
    {
        serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        IPEndPoint serverIpEndPoint = new IPEndPoint(IPAddress.Parse("服务器2IP地址"), 8889);
        serverSocket.Bind(serverIpEndPoint);
        serverSocket.Listen(5);

        while (true)
        {
            Socket clientSocket = serverSocket.Accept();
            Thread thread = new Thread(() => ClientThreadProc2(clientSocket));
            thread.Start();
        }
    }

    private void ClientThreadProc2(Socket clientSocket)
    {
        byte[] buffer = new byte[1024 * 1024];
        int count = clientSocket.Receive(buffer);
        string msg = Encoding.UTF8.GetString(buffer, 0, count);
        Console.WriteLine("服务器2接收到来自服务器1的消息:" + msg);
        clientSocket.Send(Encoding.UTF8.GetBytes("服务器2已收到你的消息:" + msg));
        clientSocket.Close();
    }
}
  • 客户端代码:
public class Client
{
    private Socket clientSocket;

    public void SendMessage(string msg)
    {
        clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        IPEndPoint server1IpEndPoint = new IPEndPoint(IPAddress.Parse("服务器1IP地址"), 8888);
        clientSocket.Connect(server1IpEndPoint);
        clientSocket.Send(Encoding.UTF8.GetBytes(msg));

        byte[] buffer = new byte[1024 * 1024];
        int count = clientSocket.Receive(buffer);
        string responseMsg = Encoding.UTF8.GetString(buffer, 0, count);
        Console.WriteLine("客户端接收到来自服务器的消息:" + responseMsg);

        clientSocket.Close();
    }
}
  • 测试代码:
static void Main(string[] args)
{
    Server1 server1 = new Server1();
    new Thread(server1.Start).Start();

    Server2 server2 = new Server2();
    new Thread(server2.Start).Start();

    Client client1 = new Client();
    new Thread(() => client1.SendMessage("来自客户端1的消息!")).Start();

    Client client2 = new Client();
    new Thread(() => client2.SendMessage("来自客户端2的消息!")).Start();

    Console.ReadLine();
}

执行以上代码后,在服务器1的控制台输出如下:

服务器1接收到来自客户端的消息:来自客户端1的消息!
服务器1接收到来自服务器2的响应消息:服务器2已收到你的消息:来自客户端1的消息!

在服务器2的控制台输出如下:

服务器2接收到来自服务器1的消息:来自客户端1的消息!

客户端1的控制台输出如下:

客户端接收到来自服务器的消息:服务器2已收到你的消息:来自客户端1的消息!

客户端2的控制台输出如下:

客户端接收到来自服务器的消息:服务器2已收到你的消息:来自客户端2的消息!

可以看出,客户端发送的消息经过服务器1转发到服务器2,并返回响应消息。同时,服务器1和服务器2也可以进行相互之间的通讯。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:c#多线程网络聊天程序代码分享(服务器端和客户端) - Python技术站

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

相关文章

  • 将Access数据库中数据导入到SQL Server中的详细方法实例

    下面是将Access数据库中数据导入到SQL Server中的详细方法实例。 1. 概述 Access是Microsoft Office套件中的一个关系型数据库程序,而SQL Server是Microsoft开发的一种关系型数据库管理系统,两者都可以用来管理数据。有时,我们需要将Access数据库中的数据导入到SQL Server中,这样可以更好地管理和处理…

    C# 2023年5月31日
    00
  • .NET中的MassTransit分布式应用框架详解

    以下是“.NET中的MassTransit分布式应用框架详解”的完整攻略: 什么是MassTransit MassTransit是一个开源的分布式应用框架,用于构建可扩展的、高可用的、松耦合的分布式应用程序。它基于消息传递模式,支持多种消息传递协议,例如RabbitMQ、Azure Service Bus、Amazon SQS等。 MassTrans的核心概…

    C# 2023年5月12日
    00
  • C#中值类型和引用类型解析

    C#中值类型和引用类型解析 值类型和引用类型的区别 在C#中,类型分为值类型和引用类型两种。值类型存储的是实际的值,引用类型存储的是该值在内存中的地址。 在调用方法时,对于值类型的参数,传递的是实际的值,而对于引用类型的参数,则传递的是该值在内存中的地址。这就导致了在对参数值进行修改时的不同表现。 对于值类型的参数,当对其进行修改时,实际上是在方法内部对其副…

    C# 2023年5月15日
    00
  • C#调用Win32的API函数–User32.dll

    下面我来详细讲解“C#调用Win32的API函数–User32.dll”的完整攻略。 什么是Win32 API Win32 API(Application Programming Interface),也叫Windows API,是Windows操作系统提供的一系列核心函数和接口,用于与操作系统打交道,访问系统资源、控制窗口和菜单等。Win32 API以动…

    C# 2023年6月7日
    00
  • C#实现单例模式的6种方法小结

    C#实现单例模式的6种方法小结 什么是单例模式? 单例模式是一种软件设计模式,它限制了某个类只能有一个实例,并且该实例可以从全局访问。单例模式通常用于控制资源的共享,并且可以避免竞态条件(race condition)。 单例模式的优点 单例模式可以保证某个类在全局范围内只有一个对象实例,这可以减少系统中的内存占用和资源消耗 单例模式可以确保某些操作只会被执…

    C# 2023年5月15日
    00
  • WinForm自定义函数FindControl实现按名称查找控件

    下面就为大家详细讲解WinForm自定义函数FindControl实现按名称查找控件的完整攻略。 一、问题描述 有时候我们需要在WinForm中查找某一个控件,但是因为控件嵌套的层次比较深,需要写很多层级查找的代码,而且这样写不太灵活,每次查找都需要改动代码。因此,我们需要自定义一个函数来实现按名称查找控件,提高效率,降低代码复杂度。如何实现按名称查找控件的…

    C# 2023年5月15日
    00
  • c#中CAD文件读取实例

    下面是关于“C#中CAD文件读取实例”的完整攻略: 1. 准备工作 在开始之前,您需要安装以下两个工具: Autodesk AutoCAD:用于创建和编辑CAD文件。 DWG TrueView:用于浏览和转换DWG格式的CAD文件。 另外,您还需要安装以下C#类库: Autodesk.AutoCAD.Runtime:用于与AutoCAD交互。 Autodes…

    C# 2023年6月1日
    00
  • C#访问C++动态分配的数组指针(实例讲解)

    初步分析这个问题,我们可以将其分为以下几个部分来进行回答: 什么是C++动态分配的数组指针? 为什么需要使用C#来访问C++动态分配的数组指针? 怎么使用C#来访问C++动态分配的数组指针? 示例说明。 下面逐一进行回答。 1. 什么是C++动态分配的数组指针? C++中的数组指针,是指指向数组的指针。动态分配的数组指针是指,程序在运行时根据需要动态分配内存…

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