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日

相关文章

  • 一篇文章说通C#的属性Attribute

    接下来我将为您详细讲解关于“一篇文章说通C#的属性Attribute”的完整攻略,该攻略的主要内容包括以下几个方面: 一、属性Attribute概述 在C#语言中,属性Attribute通常被称为为元数据,也就是代码中的数据,可以帮助我们更好地描述和扩展代码的信息。可以理解为是一种装饰着修饰代码或者类型信息的特殊语法。 二、常见的Attribute类别 C#…

    C# 2023年5月15日
    00
  • Redis中ServiceStack.Redis和StackExchange.Redis区别详解

    Redis中ServiceStack.Redis和StackExchange.Redis区别详解 1. 简介 ServiceStack.Redis和StackExchange.Redis是Redis的两个C#客户端库。它们都提供了操作Redis的API。本文将详细讲解ServiceStack.Redis和StackExchange.Redis的区别和使用方法…

    C# 2023年6月3日
    00
  • C#安装OpenCvSharp4的实现步骤

    C#安装OpenCvSharp4的实现步骤可以大概分为以下几个步骤: 安装Visual StudioOpenCvSharp4需要依赖Visual Studio,因此需要先安装Visual Studio。可以从Microsoft官网下载对应版本的Visual Studio进行安装。 安装OpenCvSharp4 NuGet包在Visual Studio中,打开…

    C# 2023年6月3日
    00
  • C# WPF数据绑定方法以及重写数据模板后数据绑定

    写在前面 本文将会介绍WPF如何实现前后端数据绑定和在进行数据绑定时常用的方法和类以及对于DataGrid、ListView这样的控件重写数据模板后控件如何进行数据绑定。 本文主要针对于数据绑定的基础实现进行介绍,通过此博文你将会有能力编写一个MVVM设计模式的C#、WPF项目。如果您是C#及WPF的资深开发人员本文可能对您没有太大的帮助,但如果你是一个正在…

    C# 2023年4月22日
    00
  • asp.net 未能加载文件或程序集“XXX”或它的某一个依赖项。试图加载格式不正确的程序。

    在ASP.NET开发中,经常会遇到“未能加载文件或程序集‘XXX’或它的某一个依赖项。试图加载格式不正确的程序”的错误提示。这个错误信息通常是由程序集加载失败所引起的,而这个问题的背后通常有两个原因:第一个原因是程序集本身缺失或损坏,第二个原因是引用的程序集发生变化。 如果遇到这个错误,可以按照以下步骤来解决: 1.重新编译项目:首先,尝试重新编译项目。打开…

    C# 2023年5月15日
    00
  • ASP.NET MVC使用Session会话保持表单状态

    以下是“ASP.NET MVC使用Session会话保持表单状态”的完整攻略: 什么是Session会话 Session会话是一种机制,用于在ASP.NET MVC应程序保持用户状态。它允许您用户之间共享数据,并在用户浏览应用程序时保持数据的持久性。 ASP.NET使用Session会话保持表单状态 是ASP.NET MVC使用Session会话保持表单状态…

    C# 2023年5月12日
    00
  • AOP从静态代理到动态代理(Emit实现)详解

    AOP从静态代理到动态代理(Emit实现)详解 概述 AOP(面向切面编程)是一种程序设计思想,可以在不改变原有代码逻辑的情况下,通过在程序中动态地新增一些逻辑代码,来实现例如日志记录、权限控制、性能监测等功能。而在 AOP 中,一个被增强的方法称为“切入点”,对该切入点进行增强的代码称为“切面”。 在实现 AOP 功能时,静态代理和动态代理是两种比较常见的…

    C# 2023年6月6日
    00
  • 快速了解c# 结构体

    下面是快速了解C#结构体的完整攻略: 简介 在C#中,结构体是一种轻量级的数据结构,可以用来封装少量相关数据。相比于类(class),结构体的运行效率更高,且占用更少的内存空间。通过使用结构体,可以提高程序的性能和效率。 定义结构体 定义结构体的方式与定义类的方式类似,不同之处在于使用“struct”关键字。例如: struct Point { public…

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