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

yizhihongxing

首先,创建一个异步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 Build 19045.3030 Release 预览版更新补丁KB5026435发布(附更新内容)

    Win10 Build 19045.3030 Release 预览版更新补丁KB5026435 发布攻略 Win10 Build 19045.3030 Release 预览版更新补丁KB5026435已发布,此次更新主要修复了一些漏洞和问题,并且引入了一些新功能和改进。接下来我们来详细解读此次更新的内容、安装方式及注意事项。 更新内容 此次更新包含了以下新功…

    Azure 2023年5月25日
    00
  • Win10版本1909Build18363.997累积更新补丁KB4559004正式推送

    关于“Win10版本1909Build18363.997累积更新补丁KB4559004正式推送”的完整攻略,包含以下内容: 1. 下载适用于你的系统的更新补丁 首先需要确认你的系统版本,可以通过打开“设置”-“系统”-“关于”进行查看。然后去微软官网下载适用于你的系统的更新补丁:- Win10版本1909及以上系统:KB4559004- Win10版本190…

    Azure 2023年5月25日
    00
  • 微软How-Old.net官方中文版上线了 幕后黑科技揭秘

    微软How-Old.net官方中文版上线了 幕后黑科技揭秘 微软的How-Old.net是一个非常有趣的在线工具,其通过上传照片来自动判断人的年龄和性别,而最近,微软宣布其官方中文版已经上线了,带来了更好的本地化体验。在这里,我将详细讲解微软How-Old.net官方中文版的使用攻略,并揭秘其背后的黑科技。 如何使用微软How-Old.net官方中文版? 使…

    Azure 2023年5月27日
    00
  • Win10 1809累积更新17763.529更新补丁KB4497934(附补丁下载与更新汇总)

    Win10 1809累积更新17763.529更新补丁KB4497934 简介 本文介绍了Win10 1809累积更新17763.529更新补丁KB4497934的相关信息,包括更新时间,更新内容、更新方法、补丁下载及更新汇总等。 更新时间 Win10 1809累积更新17763.529更新补丁KB4497934发布于2019年5月15日,是Windows …

    Azure 2023年5月26日
    00
  • Win11 Beta预览版Build 22621.870/22623.870更新补丁KB5018499发布(附完整更新日志)

    Win11 Beta预览版Build 22621.870/22623.870更新补丁KB5018499发布(附完整更新日志)攻略 什么是Win11 Beta预览版Build 22621.870/22623.870更新补丁KB5018499? Win11 Beta预览版Build 22621.870/22623.870更新补丁KB5018499是微软发布的Wi…

    Azure 2023年5月26日
    00
  • HowOldRobot怎么测年龄 微软人脸识别年龄网址

    如何使用HowOldRobot测量年龄? HowOldRobot是微软推出的一个在线工具,可以通过人脸识别技术快速测量人物年龄。使用HowOldRobot非常简单,只需要打开网页,上传照片,然后等待系统对图片进行分析和处理,最终得到一组预测年龄结果。 具体步骤如下: 打开网站:https://www.how-old.net/,进入HowOldRobot网站页…

    Azure 2023年5月25日
    00
  • elasticsearch集群cluster discovery可配式模块示例分析

    我来为你详细讲解一下“elasticsearch集群cluster discovery可配式模块示例分析”的完整攻略。 什么是elasticsearch集群cluster discovery可配式模块? elasticsearch集群cluster discovery可配式模块,是elasticsearch用于实现集群自动发现的模块,将帮助我们在不同的节点之…

    Azure 2023年5月26日
    00
  • Win11 Build 22000.651今日发布 KB5012643补丁完整更新内容汇总

    Win11 Build 22000.651今日发布 KB5012643补丁完整更新内容汇总 本文为 Win11 Build 22000.651发布的 KB5012643补丁完整更新内容汇总。此补丁为 Win11的重要更新,包含了多项性能优化和安全修复,建议所有 Win11用户安装该补丁。 更新方式 首先,您需要打开 Win11系统的设置窗口,并选择“更新和安…

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