C# HPSocket 服务器端的详细 Demo,数据收发打包方式,避免出现沾包的情况

发布时间:2024年01月20日

HPSocket 是一款跨平台的 Socket 服务器框架,支持快速开发高性能、高可靠性的网络通信应用程序。它提供了丰富的 API,可以轻松实现客户端与服务器之间的数据收发、连接管理等功能。

代码结构:
1、Program.cs:程序入口,创建 HPSocketServer 实例,启动服务器。
2、HPSocketServer:HPSocket 的服务器端实例,管理连接和通信。

功能实现:

1、接收客户端连接:服务器端循环等待客户端连接请求,创建新的连接实例。
2、接收客户端数据:通过连接实例的 DataArrived事件处理函数接收客户端发送的数据。
3、处理客户端数据:对接收到的数据进行解析和处理。
4、发送响应数据:根据处理结果,向客户端发送响应数据。

性能和安全性优化:
1、异步编程:使用异步编程模型,避免阻塞主线程,提高应用程序的响应性能。
2、数据封装:对发送和接收的数据进行封装,减少网络传输过程中的开销。
3、心跳机制:在服务器端和客户端之间添加心跳机制,保持连接的稳定性。
4、数据加密:对敏感数据进行加密处理,提高数据传输的安全性。

以下是 C# HPSocket 服务器端的详细 Demo:
Program.cs:

using System;
using System.Net.Sockets;
using System.Text;
using System.Threading;
namespace HPSocketServerDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            HPSocketServer server = new HPSocketServer();
            server.StartListening(12345);
        }
    }
}

HPSocketServer.cs:

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

public class HPSocketServer
{
    private TcpListener listener;
    private Thread listenerThread;

    public void StartListening(int port)
    {
        try
        {
            listener = new TcpListener(IPAddress.Any, port);
            listener.Start();
            listenerThread = new Thread(ListenForIncomingRequests);
            listenerThread.IsBackground = true;
            listenerThread.Start();
            Console.WriteLine("服务器启动,等待客户端连接...");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"启动服务器失败:{ex.Message}");
        }
    }

    private void ListenForIncomingRequests()
    {
        while (true)
        {
            try
            {
                TcpClient client = listener.AcceptTcpClient();
                Console.WriteLine("新的客户端连接");

                // 创建连接实例,并启动数据接收线程
                HPSocketConnection connection = new HPSocketConnection(client);
                connection.DataReceived += Connection_DataReceived;
                connection.StartListening();
            }
            catch (Exception ex)
            {
                Console.WriteLine($"处理客户端连接失败:{ex.Message}");
            }
        }
    }

    private void Connection_DataReceived(object sender, HPSocketConnectionDataArgs e)
    {
        byte[] data = e.Data;
        string received = Encoding.UTF8.GetString(data);
        Console.WriteLine($"接收到的数据:{received}");

        // 处理数据,并发送响应
        string response = ProcessData(received);
        byte[] responseData = Encoding.UTF8.GetBytes(response);
        ((HPSocketConnection)sender).Send(responseData);
    }

    private string ProcessData(string data)
    {
        // 这里可以根据需要对数据进行处理,并返回响应
        return $"服务器响应:{data}";
    }
}

class HPSocketConnection
{
    private TcpClient client;
    private Thread listenThread;
    private bool isListening = true;

    public event DataReceivedEventHandler DataReceived;

    public HPSocketConnection(TcpClient client)
    {
        this.client = client;
    }

    public void StartListening()
    {
        listenThread = new Thread(ListenForData);
        listenThread.IsBackground = true;
        listenThread.Start();
    }

    private void ListenForData()
    {
        try
        {
            using (NetworkStream stream = client.GetStream())
            {
                byte[] buffer = new byte[1024];

                while (isListening && client.Connected)
                {
                    int bytesRead = stream.Read(buffer, 0, buffer.Length);
                    if (bytesRead == 0)
                    {
                        break;
                    }

                    byte[] data = new byte[bytesRead];
                    Array.Copy(buffer, data, bytesRead);
                    string received = Encoding.UTF8.GetString(data);

                    OnDataReceived(received);
                }
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine($"数据接收失败:{ex.Message}");
        }
    }

    protected virtual void OnDataReceived(string data)
    {
        DataReceivedEventHandler handler = DataReceived;
        if (handler != null)
        {
            handler(this, new DataReceivedEventArgs(data));
        }
    }

    public void Send(byte[] data)
    {
        try
        {
            using (NetworkStream stream = client.GetStream())
            {
                stream.Write(data, 0, data.Length);
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine($"发送数据失败:{ex.Message}");
        }
    }

    public void StopListening()
    {
        isListening = false;
        listenThread.Join();
    }
}

public delegate void DataReceivedEventHandler(object sender, DataReceivedEventArgs e);

public class DataReceivedEventArgs : EventArgs
{
    public string Data { get; }

    public DataReceivedEventArgs(string data)
    {
        Data = data;
    }
}

在这个示例中,我们创建了一个 HPSocketServer 类,它负责启动 TcpListener 并监听 incoming requests。当一个客户端连接时,它会创建一个新的 HPSocketConnection 实例并启动一个单独的线程来处理该连接。

HPSocketConnection 类负责处理与客户端的通信。它有一个 DataReceived 事件,当接收到数据时会触发。服务器端的数据处理是通过 DataReceived 事件处理器来完成的。数据发送是通过 Send 方法实现的。

为了处理沾包和拆包的问题,我们在 HPSocketConnection 类中使用了一个循环来不断地从网络流中读取数据,直到连接断开或读取到 0 个字节。这样,我们可以确保即使数据跨越了多个网络包,也能够正确地接收到。

在实际应用中,你可能需要根据实际需求对数据包进行更复杂的处理,例如添加长度字段、校验和或使用更高级的协议来确保数据的完整性和可靠性。

请注意,这个示例是一个简单的 HPSocket 服务器实现,它没有实现错误处理、加密或其他安全性措施。在生产环境中,你应该添加适当的错误处理、日志记录、数据加密和其他安全措施来保护你的应用程序。

文章来源:https://blog.csdn.net/qq_35320456/article/details/135682807
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。