使用C#来编写一个异步的Socket服务器

首先,创建一个异步Socket服务器需要进行以下步骤:

  1. 创建Socket监听端口
  2. 等待连接
  3. 接收连接并分配线程进行处理
  4. 给客户端发送信息
  5. 关闭连接

下面我们来一步步讲解具体实现。

创建Socket监听端口

创建Socket监听端口相关的代码如下所示:

using System.Net;
using System.Net.Sockets;

public void StartServer()
{
    Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    listener.Bind(new IPEndPoint(IPAddress.Any, 8080)); // 监听 8080 端口
    listener.Listen(5); // 设置监听队列长度为 5

    Console.WriteLine("Server is listening...");

    while(true)
    {
        Socket clientSocket = await Task.Factory.FromAsync(listener.BeginAccept, listener.EndAccept, null);
        Console.WriteLine("Client connected.");

        // 连接成功后,分配任务并等待下一个连接
        Task.Run(() => ProcessClient(clientSocket));
    }
}

在 StartServer() 方法中,我们创建了一个Socket实例,然后调用 Bind() 方法来将其绑定到本地任意IP地址和8080端口,最后调用 Listen() 方法来开始监听。

等待连接

创建Socket监听后,我们需要等待连接。这个过程需要一直不断地运行,直到进程关闭。具体实现代码如下:

public async Task AcceptLoop(Socket listener)
{
    while (true)
    {
        var client = await Task.Factory.FromAsync(listener.BeginAccept, listener.EndAccept, null);
        Console.WriteLine("Client connected.");

        Task.Factory.StartNew(() => ProcessClient(client));
    }
}

在 AcceptLoop() 方法中,我们使用了一个while循环,不停地等待新的连接。这个方法使用了异步等待,意味着它会释放线程资源并等待下一个客户端请求。

接收连接并分配线程进行处理

连接被接受后,我们需要为该连接分配一个新的线程来对该连接进行处理。下面的代码实现了这一功能:

public void ProcessClient(Socket clientSocket)
{
    // 处理客户端请求
    try
    {
        // 接收客户端数据
        byte[] buffer = new byte[1024];
        int length = clientSocket.Receive(buffer);

        Console.WriteLine("Received: {0}", Encoding.ASCII.GetString(buffer, 0, length));

        // 给客户端发送响应数据
        string response = "Hello from server";
        clientSocket.Send(Encoding.ASCII.GetBytes(response));
    }
    catch (Exception e)
    {
        Console.WriteLine("Error: " + e.Message);
    }
    finally
    {
        // 关闭连接
        clientSocket.Close();
    }
}

在 ProcessClient() 方法中,我们首先接收客户端发送的数据,然后对其进行处理,最后将响应数据发送回客户端,并关闭该连接。

给客户端发送信息

Socket服务器的一个基本功能是能够给客户端发送信息,下面是一段实现这一功能的代码:

public void SendMessage(Socket clientSocket, string message)
{
    byte[] buffer = Encoding.ASCII.GetBytes(message);
    clientSocket.Send(buffer);
}

这段代码接收一个Socket实例和一个发送消息的字符串,然后将该字符串转换为一个字节数组,并将其发送给Socket服务器。

关闭连接

在服务器的处理完成之后,我们需要关闭连接以释放资源,下面的代码提供了关闭连接的实现:

public void CloseClient(Socket clientSocket)
{
    try
    {
        clientSocket.Shutdown(SocketShutdown.Both);
    }
    catch (Exception e)
    {
        Console.WriteLine("Error: " + e.Message);
    }
    finally
    {
        clientSocket.Close();
    }
}

这段代码通过调用 Shutdown() 方法来关闭连接,然后使用 Close() 方法来释放所有相关的资源。

下面是一个完整的示例,用C#实现了一个简单的Echo服务器:

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

namespace MySocketServer
{
    class Program
    {
        static void Main(string[] args)
        {
            var server = new SocketServer();
            server.Start();
            Console.ReadLine();
        }
    }

    public class SocketServer
    {
        public async void Start()
        {
            try
            {
                var listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                listener.Bind(new IPEndPoint(IPAddress.Any, 8080));
                listener.Listen(5);

                Console.WriteLine("Server is listening...");
                await AcceptLoop(listener);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
        }

        public async Task AcceptLoop(Socket listener)
        {
            while (true)
            {
                var client = await Task.Factory.FromAsync(listener.BeginAccept, listener.EndAccept, null);
                Console.WriteLine("Client connected.");

                Task.Factory.StartNew(() => ProcessClient(client));
            }
        }

        public void ProcessClient(Socket clientSocket)
        {
            try
            {
                byte[] buffer = new byte[1024];
                int length = clientSocket.Receive(buffer);

                Console.WriteLine("Received: {0}", Encoding.ASCII.GetString(buffer, 0, length));

                string message = Encoding.ASCII.GetString(buffer, 0, length);

                SendMessage(clientSocket, message);
            }
            catch (Exception e)
            {
                Console.WriteLine("Error: " + e.Message);
            }
            finally
            {
                CloseClient(clientSocket);
            }
        }

        public void SendMessage(Socket clientSocket, string message)
        {
            byte[] buffer = Encoding.ASCII.GetBytes(message);
            clientSocket.Send(buffer);
        }

        public void CloseClient(Socket clientSocket)
        {
            try
            {
                clientSocket.Shutdown(SocketShutdown.Both);
            }
            catch (Exception e)
            {
                Console.WriteLine("Error: " + e.Message);
            }
            finally
            {
                clientSocket.Close();
            }
        }
    }
}

此示例创建了一个Socket服务器,它监听8080端口,并在客户端连接到它时将任何发送的数据回显回去。当客户端断开连接时,服务器会释放使用的资源。

另外,根据需要,可以根据上述示例自定义指定的端口和消息响应方式,以满足更多的Server需求。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:使用C#来编写一个异步的Socket服务器 - Python技术站

(0)
上一篇 2023年5月25日
下一篇 2023年5月25日

相关文章

  • Win10周年更新14393.82和累积更新KB3176936/KB3176934补丁

    Win10周年更新14393.82和累积更新KB3176936/KB3176934是Win10系统更新的重要补丁,能够修复系统缺陷提高系统的稳定性和安全性,以下为相关攻略。 Win10周年更新14393.82 Win10周年更新14393.82是Win10系统的一次大规模更新,其中包括修复了许多BUG并且针对系统蓝屏、CPU占用过高、系统卡顿等问题进行了优化…

    Azure 2023年5月25日
    00
  • Sql Server数据库各版本功能对比

    Sql Server数据库各版本功能对比 本文将对Sql Server数据库不同版本的功能进行对比,以便用户根据自身需求选择适合的版本。 Sql Server 2017 Sql Server 2017是Sql Server系列中的最新版本,在功能上有很多的创新和升级。主要更新如下: Graph数据处理引擎 移动领域和社交网络分析使用最为广泛。 自然语言处理 …

    Azure 2023年5月25日
    00
  • Asp.net SignalR支持的平台有哪些

    Asp.net SignalR是一个用于构建实时Web应用程序的开源库。它可以支持多种平台,包括以下几个方面: 支持的运行环境 Asp.net SignalR可以在多种运行环境中使用,其中包括: Asp.net:SignalR可以轻松集成到Asp.net应用程序中,并通过ASP.NET核心、MVC或Web API进行开发。 Windows桌面应用程序:Sig…

    Azure 2023年5月25日
    00
  • 2021最新win10系统怎么激活 win10激活秘钥/激活码推荐 附激活工具

    2021最新win10系统怎么激活 如果你使用一直未激活的 Windows 10,你将会遭受一些限制。例如,无法个性化系统,不能更改背景,会不时遇到弹窗提示激活系统等。这时候,我们需要进行激活。下面介绍一些 win10激活秘钥/激活码的推荐和附带激活工具。 win10激活秘钥/激活码推荐 激活秘钥需要从合法途径获取。以下是几个可行的途径: 从微软官网购买正版…

    Azure 2023年5月26日
    00
  • win10 iOS镜像版激活秘钥/神key分享 附kms激活工具+教程

    本文主要介绍如何使用win10 iOS镜像版来激活操作系统,并提供相应的激活秘钥和工具。 1. 下载win10 iOS镜像版 首先需要下载win10 iOS镜像版,可以在网上搜索下载链接。下载完成后将镜像文件制作成安装盘或USB启动盘。 2. 安装win10 iOS镜像版 使用制作好的安装盘或USB启动盘进行系统安装。在安装过程中,按照提示进行相应的设置,如…

    Azure 2023年5月25日
    00
  • PostgreSQL备份工具 pgBackRest使用详解

    PostgreSQL备份工具 pgBackRest使用详解 pgBackRest是一个可靠、高效、功能丰富的 PostgreSQL 备份和恢复工具,本文将详细介绍如何使用此工具。 安装 pgBackRest 可在 Linux 和 macOS 上运行,并且可通过应用程序包管理器进行安装,也可以直接从源代码进行安装。 应用程序包管理器安装 如果您使用的是 Red…

    Azure 2023年5月25日
    00
  • win10系统激活失效怎么办 最新win10激活秘钥分享 附激活工具

    Win10系统激活失效解决攻略 1. 检查激活状态 首先需要检查当前系统的激活状态,可以按下Win+R键打开运行窗口,输入cmd并按下Enter键,打开命令提示符窗口,在窗口中输入slmgr -xpr并按下Enter,即可查看当前系统激活状态。 如果提示 “Windows已经激活,可使用” 字样,则说明系统已经成功激活,此时问题出在别处;如果提示 “Wind…

    Azure 2023年5月25日
    00
  • Linux的发展不容小觑(独霸天下) 未来将渗透到生活的方方面面

    Linux的发展不容小觑 Linux是一种免费的、开源的操作系统,具有高度的可定制性和安全性。虽然Linux的历史相对于其他操作系统比起来还比较短暂,但Linux的发展在过去几十年中却非常不容小觑,它不仅在服务器领域占有重要地位,而且正在逐步走向其他领域,如移动设备、智能家居、汽车等等。 Linux在服务器领域的独霸地位 Linux在服务器领域的使用率非常高…

    Azure 2023年5月25日
    00
合作推广
合作推广
分享本页
返回顶部