c#和form实现WebSocket在线聊天室

news2025/4/16 7:45:15

c#和form实现WebSocket在线聊天室
功能点

 
后端程序 (Program.cs)

​​1.WebSocket 聊天服务器核心功能​​
	a.管理客户端连接(ConnectionManager 类)
	b.支持公聊消息广播(所有用户可见)
	c.支持私聊消息(通过 @用户ID 格式指定接收方)
	d.自动广播用户加入/离开通知
	e.实时同步在线用户列表
	f.消息时间戳记录(精确到秒)

​​2.HTTP 服务增强功能​​
	a.提供 /hello 测试端点(经典 "Hello World")
	b.完整的 WebSocket 握手协议支持
	c.详细的 HTTP 请求日志记录(包含请求头/响应体)
	d.性能监控中间件(记录请求处理耗时)

​​3.技术特性​​
	a.线程安全的并发连接管理(ConcurrentDictionary)
	b.JSON 序列化优化(驼峰式命名策略)
	c.WebSocket 消息完整接收保障(分帧消息合并)
	d.强类型消息模型(使用 C# 9 record 类型)


客户端程序 (Form1.cs)

​​1.用户界面功能​​
	a.双栏布局:左侧在线用户列表,右侧聊天区
	b.彩色消息区分(系统消息灰色、公聊蓝色、私聊紫色)
	c.自动滚动保持最新消息可见
	d.支持回车键快速发送(Shift+Enter 换行)
	e.用户列表动态更新(双击可查看用户 ID)

​​2.聊天功能实现​​
	a.自动生成唯一用户标识(GUID 简化形式)
	b.智能消息解析(自动识别私聊语法 @用户ID 内容)
	c.断线重连处理(需手动重开客户端)
	d.消息本地持久化(窗体关闭前保留聊天记录)

​​3.技术亮点​​
	a.异步 WebSocket 通信(非阻塞 UI)
	b.跨线程 UI 更新安全机制(Control.Invoke)
	c.JSON 消息高效解析(JsonDocument 流式处理)
	d.自适应窗体布局(百分比尺寸分配)

 

效果图:
在这里插入图片描述

step1: service socket
C:\Users\wangrusheng\RiderProjects\WebApplication4\WebApplication4\Program.cs

using System.Collections.Concurrent;
using System.Net.WebSockets;
using System.Text;
using System.Text.Json;
using Microsoft.AspNetCore.HttpLogging;

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddSingleton<ConnectionManager>();
// 添加控制台日志和调试日志
builder.Logging.AddConsole()
    .AddDebug()
    .SetMinimumLevel(LogLevel.Debug);

// 配置HTTP日志
builder.Services.AddHttpLogging(logging =>
{
    logging.LoggingFields = HttpLoggingFields.All;
    logging.RequestHeaders.Add("sec-ch-ua");
    logging.ResponseHeaders.Add("MyResponseHeader");
    logging.MediaTypeOptions.AddText("application/json");
    logging.RequestBodyLogLimit = 4096;
    logging.ResponseBodyLogLimit = 4096;
});
var app = builder.Build();

// 使用请求日志中间件(必须放在其他中间件之前)
app.UseHttpLogging();

// 自定义请求日志中间件
app.Use(async (context, next) => {
    var logger = context.RequestServices.GetRequiredService<ILogger<Program>>();
    
    logger.LogInformation($"Request Start: {context.Request.Method} {context.Request.Path}");
    var startTime = DateTime.UtcNow;
    
    await next();
    
    var elapsed = (DateTime.UtcNow - startTime).TotalMilliseconds;
    logger.LogInformation($"Request End: {context.Response.StatusCode} - {elapsed}ms");
});

// 启用WebSocket支持
app.UseWebSockets();

// 保留原有Hello World端点
app.MapGet("/hello", () => "Hello World!");

// WebSocket聊天室端点
app.Map("/ws", async context =>
{
    if (context.WebSockets.IsWebSocketRequest)
    {
        var webSocket = await context.WebSockets.AcceptWebSocketAsync();
        var manager = context.RequestServices.GetRequiredService<ConnectionManager>();
        await manager.HandleConnectionAsync(webSocket);
    }
    else
    {
        context.Response.StatusCode = StatusCodes.Status400BadRequest;
    }
});

await app.RunAsync();

public class ConnectionManager
{
    private readonly ConcurrentDictionary<string, ClientInfo> _clients = new();
    private readonly JsonSerializerOptions _jsonOptions = new() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase };

    public async Task HandleConnectionAsync(WebSocket webSocket)
    {
        var clientId = Guid.NewGuid().ToString()[..8];
        var initMessage = await ReceiveFullMessage(webSocket);
        var initData = JsonSerializer.Deserialize<Dictionary<string, string>>(initMessage, _jsonOptions);
        var username = initData!["username"];

        var clientInfo = new ClientInfo(webSocket, username, clientId);
        _clients.TryAdd(clientId, clientInfo);

        await BroadcastSystemMessage($"{username} 进入聊天室");
        await BroadcastUserList();

        try
        {
            while (webSocket.State == WebSocketState.Open)
            {
                var message = await ReceiveFullMessage(webSocket);
                await ProcessMessage(clientInfo, message);
            }
        }
        finally
        {
            _clients.TryRemove(clientId, out _);
            await BroadcastSystemMessage($"{username} 已离开");
            await BroadcastUserList();
        }
    }

    private async Task ProcessMessage(ClientInfo sender, string rawMessage)
    {
        var message = JsonSerializer.Deserialize<Dictionary<string, object>>(rawMessage, _jsonOptions)!;
        var type = message["type"].ToString()!;

        switch (type)
        {
            case "public":
                await BroadcastPublicMessage(sender, message["content"].ToString()!);
                break;
            case "private":
                await SendPrivateMessage(
                    sender,
                    message["to"].ToString()!,
                    message["content"].ToString()!
                );
                break;
        }
    }

    private async Task BroadcastPublicMessage(ClientInfo sender, string content)
    {
        var message = new PublicMessage(
            "public",
            sender.ClientId,
            sender.Username,
            content,
            DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")
        );

        await BroadcastMessage(JsonSerializer.Serialize(message, _jsonOptions));
    }

    private async Task SendPrivateMessage(ClientInfo sender, string receiverId, string content)
    {
        if (!_clients.TryGetValue(receiverId, out var receiver)) return;

        var message = new PrivateMessage(
            "private",
            sender.ClientId,
            receiverId,
            sender.Username,
            content,
            DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")
        );

        var json = JsonSerializer.Serialize(message, _jsonOptions);
        await SendMessageAsync(sender.WebSocket, json);
        await SendMessageAsync(receiver.WebSocket, json);
    }

    private async Task BroadcastSystemMessage(string content)
    {
        var message = new SystemMessage(
            "system",
            content,
            DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")
        );

        await BroadcastMessage(JsonSerializer.Serialize(message, _jsonOptions));
    }

    private async Task BroadcastUserList()
    {
        var users = _clients.Values.Select(c => new UserInfo(c.ClientId, c.Username)).ToList();
        var message = new UserListMessage("user_list", users);
        await BroadcastMessage(JsonSerializer.Serialize(message, _jsonOptions));
    }

    private async Task BroadcastMessage(string message)
    {
        var buffer = Encoding.UTF8.GetBytes(message);
        foreach (var client in _clients.Values.Where(c => c.WebSocket.State == WebSocketState.Open))
        {
            await client.WebSocket.SendAsync(
                new ArraySegment<byte>(buffer),
                WebSocketMessageType.Text,
                true,
                CancellationToken.None
            );
        }
    }

    private static async Task<string> ReceiveFullMessage(WebSocket webSocket)
    {
        var buffer = new byte[1024 * 4];
        var message = new List<byte>();
        WebSocketReceiveResult result;

        do
        {
            result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
            message.AddRange(new ArraySegment<byte>(buffer, 0, result.Count));
        } while (!result.EndOfMessage);

        return Encoding.UTF8.GetString(message.ToArray());
    }

    private static async Task SendMessageAsync(WebSocket webSocket, string message)
    {
        var bytes = Encoding.UTF8.GetBytes(message);
        await webSocket.SendAsync(
            new ArraySegment<byte>(bytes),
            WebSocketMessageType.Text,
            true,
            CancellationToken.None
        );
    }

    private record ClientInfo(WebSocket WebSocket, string Username, string ClientId);
    private record UserInfo(string ClientId, string Username);
    private record PublicMessage(string Type, string From, string SenderName, string Content, string Timestamp);
    private record PrivateMessage(string Type, string From, string To, string SenderName, string Content, string Timestamp);
    private record SystemMessage(string Type, string Content, string Timestamp);
    private record UserListMessage(string Type, List<UserInfo> Users);
}

step1:client console
C:\Users\wangrusheng\RiderProjects\ConsoleApp4\ConsoleApp4\Program.cs

using System.Net.WebSockets;
using System.Text;
using System.Text.Json;

class Program
{
    static async Task Main(string[] args)
    {
        Console.Write("请输入用户名: ");
        var username = Console.ReadLine()!;

        using var ws = new ClientWebSocket();
        await ws.ConnectAsync(new Uri("ws://localhost:5079/ws"), CancellationToken.None);

        // 发送初始化信息
        var initMessage = JsonSerializer.Serialize(new { username });
        await Send(ws, initMessage);

        // 启动接收任务
        var receiveTask = ReceiveMessages(ws);
        var sendTask = SendMessages(ws);

        await Task.WhenAll(receiveTask, sendTask);
    }

    static async Task SendMessages(ClientWebSocket ws)
    {
        var jsonOptions = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase };

        while (true)
        {
            Console.WriteLine("\n输入消息格式:\n1. 群发消息 → 直接输入\n2. 私聊消息 → @用户ID 内容\n3. 退出 → exit");
            var input = Console.ReadLine();

            if (string.IsNullOrEmpty(input)) continue;

            if (input.Equals("exit", StringComparison.OrdinalIgnoreCase))
            {
                await ws.CloseAsync(WebSocketCloseStatus.NormalClosure, null, CancellationToken.None);
                return;
            }

            if (input.StartsWith("@"))
            {
                var parts = input.Split(new[] { ' ' }, 2, StringSplitOptions.RemoveEmptyEntries);
                if (parts.Length == 2)
                {
                    var message = new
                    {
                        type = "private",
                        to = parts[0][1..],
                        content = parts[1]
                    };
                    await Send(ws, JsonSerializer.Serialize(message, jsonOptions));
                }
            }
            else
            {
                var message = new { type = "public", content = input };
                await Send(ws, JsonSerializer.Serialize(message, jsonOptions));
            }
        }
    }

    static async Task ReceiveMessages(ClientWebSocket ws)
    {
        var buffer = new byte[4096];
        var jsonOptions = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase };

        try
        {
            while (ws.State == WebSocketState.Open)
            {
                var result = await ws.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
                if (result.MessageType == WebSocketMessageType.Text)
                {
                    var message = Encoding.UTF8.GetString(buffer, 0, result.Count);
                    HandleMessage(message, jsonOptions);
                }
            }
        }
        catch (WebSocketException)
        {
            Console.WriteLine("连接已断开");
        }
    }

    static void HandleMessage(string jsonMessage, JsonSerializerOptions options)
    {
        using var doc = JsonDocument.Parse(jsonMessage);
        var root = doc.RootElement;
        var type = root.GetProperty("type").GetString()!;

        switch (type)
        {
            case "user_list":
                PrintUserList(root);
                break;
            case "private":
                PrintPrivateMessage(root);
                break;
            case "public":
                PrintPublicMessage(root);
                break;
            case "system":
                PrintSystemMessage(root);
                break;
        }
    }

    static void PrintUserList(JsonElement element)
    {
        Console.WriteLine("\n" + new string('=', 50));
        Console.WriteLine("在线用户列表:");
        foreach (var user in element.GetProperty("users").EnumerateArray())
        {
            Console.WriteLine($"  {user.GetProperty("clientId").GetString()} | {user.GetProperty("username").GetString()}");
        }
        Console.WriteLine(new string('=', 50));
    }

    static void PrintPrivateMessage(JsonElement element)
    {
        Console.WriteLine($"\n[私聊] {element.GetProperty("senderName").GetString()} ({element.GetProperty("timestamp").GetString()}):");
        Console.WriteLine($"  {element.GetProperty("content").GetString()}");
    }

    static void PrintPublicMessage(JsonElement element)
    {
        Console.WriteLine($"\n[公共] {element.GetProperty("senderName").GetString()} ({element.GetProperty("timestamp").GetString()}):");
        Console.WriteLine($"  {element.GetProperty("content").GetString()}");
    }

    static void PrintSystemMessage(JsonElement element)
    {
        Console.WriteLine($"\n[系统] {element.GetProperty("timestamp").GetString()}:");
        Console.WriteLine($"  {element.GetProperty("content").GetString()}");
    }

    static async Task Send(ClientWebSocket ws, string message)
    {
        var bytes = Encoding.UTF8.GetBytes(message);
        await ws.SendAsync(new ArraySegment<byte>(bytes), WebSocketMessageType.Text, true, CancellationToken.None);
    }
}

step3:client form
C:\Users\wangrusheng\RiderProjects\WinFormsApp33\WinFormsApp33\Form1.cs

using System;
using System.Drawing;
using System.Net.WebSockets;
using System.Text;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WinFormsApp33
{
    

    public partial class Form1 : Form
    { 
    
     
        private readonly ClientWebSocket _ws = new ClientWebSocket();
        private readonly JsonSerializerOptions _jsonOptions = new JsonSerializerOptions
        {
            PropertyNamingPolicy = JsonNamingPolicy.CamelCase
        };

        // 控件声明
        private ListView lstUsers;
        private RichTextBox txtChat;
        private TextBox txtInput;
        private Button btnSend;

        // 用户信息
        private readonly string _clientId;
        private readonly string _username;

        public Form1()
        {
            // 生成固定用户信息
            _clientId = Guid.NewGuid().ToString("N")[..6];
            _username = $"用户_{_clientId}";

            InitializeComponent();
            SetupUI();
            this.Load += MainForm_Load;
        }

        private void SetupUI()
        {
            // 窗体设置
            this.Text = $"{_username} - 聊天客户端";
            this.Size = new Size(800, 600);
            this.StartPosition = FormStartPosition.CenterScreen;
            this.FormClosing += MainForm_FormClosing;

            // 主布局面板
            var mainTable = new TableLayoutPanel
            {
                Dock = DockStyle.Fill,
                ColumnCount = 2,
                RowCount = 1
            };
            mainTable.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 25F));
            mainTable.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 75F));

            // 左侧用户列表
            var userPanel = new GroupBox
            {
                Text = "在线用户",
                Dock = DockStyle.Fill
            };
            lstUsers = new ListView
            {
                View = View.Details,
                FullRowSelect = true,
                Dock = DockStyle.Fill
            };
            lstUsers.Columns.Add("ID", 80);
            lstUsers.Columns.Add("用户名", 120);
            userPanel.Controls.Add(lstUsers);
            mainTable.Controls.Add(userPanel, 0, 0);

            // 右侧聊天区
            var chatPanel = new TableLayoutPanel
            {
                Dock = DockStyle.Fill,
                RowCount = 2
            };
            chatPanel.RowStyles.Add(new RowStyle(SizeType.Percent, 85F));
            chatPanel.RowStyles.Add(new RowStyle(SizeType.Percent, 15F));

            // 聊天记录显示
            txtChat = new RichTextBox
            {
                Dock = DockStyle.Fill,
                ReadOnly = true,
                BackColor = Color.White,
                Font = new Font("微软雅黑", 10)
            };
            chatPanel.Controls.Add(txtChat, 0, 0);

            // 输入区
            var inputPanel = new Panel
            {
                Dock = DockStyle.Fill
            };
            txtInput = new TextBox
            {
                Dock = DockStyle.Fill,
                Multiline = true,
                Font = new Font("微软雅黑", 10),
                AcceptsReturn = true
            };
            txtInput.KeyDown += TxtInput_KeyDown;
            
            btnSend = new Button
            {
                Text = "发送",
                Dock = DockStyle.Right,
                Width = 80,
                Font = new Font("微软雅黑", 10)
            };
            btnSend.Click += BtnSend_Click;
            
            inputPanel.Controls.Add(btnSend);
            inputPanel.Controls.Add(txtInput);
            chatPanel.Controls.Add(inputPanel, 0, 1);

            mainTable.Controls.Add(chatPanel, 1, 0);

            this.Controls.Add(mainTable);
        }

        private async void MainForm_Load(object sender, EventArgs e)
        {
            await ConnectToServer();
        }

        private async Task ConnectToServer()
        {
            try
            {
                await _ws.ConnectAsync(new Uri("ws://localhost:5079/ws"), CancellationToken.None);
                var initMessage = JsonSerializer.Serialize(new { username = _username });
                await SendMessage(initMessage);
                _ = Task.Run(() => ReceiveMessages());
            }
            catch (Exception ex)
            {
                MessageBox.Show($"连接失败: {ex.Message}");
                this.Close();
            }
        }

        private async Task SendMessage(string message)
        {
            var bytes = Encoding.UTF8.GetBytes(message);
            await _ws.SendAsync(new ArraySegment<byte>(bytes), 
                WebSocketMessageType.Text, 
                true, 
                CancellationToken.None);
        }

        private async Task ReceiveMessages()
        {
            var buffer = new byte[4096];
            try
            {
                while (_ws.State == WebSocketState.Open)
                {
                    var result = await _ws.ReceiveAsync(new ArraySegment<byte>(buffer), 
                        CancellationToken.None);
                    if (result.MessageType == WebSocketMessageType.Text)
                    {
                        var message = Encoding.UTF8.GetString(buffer, 0, result.Count);
                        ProcessMessage(message);
                    }
                }
            }
            catch (Exception ex)
            {
                AppendSystemMessage($"连接异常: {ex.Message}");
            }
        }

        private void ProcessMessage(string jsonMessage)
        {
            using var doc = JsonDocument.Parse(jsonMessage);
            var root = doc.RootElement;
            var type = root.GetProperty("type").GetString();

            this.Invoke((MethodInvoker)delegate
            {
                try
                {
                    switch (type)
                    {
                        case "user_list":
                            UpdateUserList(root);
                            break;
                        case "public":
                        case "private":
                        case "system":
                            AppendChatMessage(root);
                            break;
                    }
                }
                catch (Exception ex)
                {
                    AppendSystemMessage($"消息处理错误: {ex.Message}");
                }
            });
        }

        private void UpdateUserList(JsonElement element)
        {
            lstUsers.BeginUpdate();
            lstUsers.Items.Clear();
            
            foreach (var user in element.GetProperty("users").EnumerateArray())
            {
                var item = new ListViewItem(user.GetProperty("clientId").GetString());
                item.SubItems.Add(user.GetProperty("username").GetString());
                lstUsers.Items.Add(item);
            }
            
            lstUsers.EndUpdate();
        }

        private void AppendChatMessage(JsonElement message)
        {
            var type = message.GetProperty("type").GetString();
            var timestamp = message.GetProperty("timestamp").GetString();
            var content = message.GetProperty("content").GetString();
            var senderName = message.TryGetProperty("senderName", out var sn) ? sn.GetString() : "系统";

            var prefix = type switch
            {
                "public" => $"[{timestamp}] {senderName}:",
                "private" => $"[{timestamp}] 私聊来自 {senderName}:",
                "system" => $"[系统通知 {timestamp}] ",
                _ => ""
            };

            txtChat.SelectionColor = type switch
            {
                "public" => Color.Blue,
                "private" => Color.Purple,
                "system" => Color.Gray,
                _ => Color.Black
            };

            txtChat.AppendText(prefix + content + "\n");
            txtChat.ScrollToCaret();
        }

        private void AppendSystemMessage(string message)
        {
            txtChat.SelectionColor = Color.Gray;
            txtChat.AppendText($"[系统] {DateTime.Now:HH:mm:ss} {message}\n");
            txtChat.ScrollToCaret();
        }

        private async void BtnSend_Click(object sender, EventArgs e)
        {
            await SendMessageAsync();
        }

        private async void TxtInput_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter && !e.Shift)
            {
                e.SuppressKeyPress = true;
                await SendMessageAsync();
            }
        }

        private async Task SendMessageAsync()
        {
            if (string.IsNullOrWhiteSpace(txtInput.Text)) return;

            var message = txtInput.Text.Trim();
            txtInput.Clear();

            try
            {
                if (message.StartsWith("@"))
                {
                    var parts = message.Split(new[] { ' ' }, 2);
                    if (parts.Length == 2)
                    {
                        var msg = new
                        {
                            type = "private",
                            to = parts[0][1..],
                            content = parts[1]
                        };
                        await SendMessage(JsonSerializer.Serialize(msg, _jsonOptions));
                    }
                }
                else
                {
                    var msg = new { type = "public", content = message };
                    await SendMessage(JsonSerializer.Serialize(msg, _jsonOptions));
                }
            }
            catch (Exception ex)
            {
                AppendSystemMessage($"发送失败: {ex.Message}");
            }
        }

        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (_ws?.State == WebSocketState.Open)
            {
                _ws.CloseAsync(WebSocketCloseStatus.NormalClosure, 
                    "Closing", 
                    CancellationToken.None).Wait();
            }
        }
    }
}

end

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2334978.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

量子代理签名:量子时代的数字授权革命

1. 量子代理签名的定义与核心原理 量子代理签名&#xff08;Quantum Proxy Signature, QPS&#xff09;是经典代理签名在量子信息领域的延伸&#xff0c;允许原始签名者&#xff08;Original Signer&#xff09;授权给代理签名者&#xff08;Proxy Signer&#xff09;代为签署文…

「Unity3D」TextMeshPro中的TMP_InputField,用来实现输入框的几个小问题

第一&#xff0c;正确设置Scrollbar。 设置Scrollbar之后&#xff0c;不能设置Text Component的Font Size为Auto Size&#xff0c;否则Scrollbar无法正确计算显示。 那么&#xff0c;要想自动适配字体大小&#xff0c;可以让Placeholder中的Font Size设置为Auto&#xff0c;这…

Docker 介绍 · 安装详细教程

为什么选择 Docker&#xff1f; ✅ 环境一致性 – 告别“在我机器上能跑”的问题&#xff0c;确保开发、测试、生产环境一致。 ✅ 高效轻量 – 秒级启动&#xff0c;资源占用远低于传统虚拟机。 ✅ 跨平台支持 – 可在任何支持 Docker 的环境中运行&#xff0c;包括云服务器、…

vulnhub:sunset decoy

靶机下载地址https://www.vulnhub.com/entry/sunset-decoy,505/ 渗透过程 简单信息收集 nmap 192.168.56.0/24 -Pn # 确定靶机ip&#xff1a;192.168.56.121 nmap 192.168.56.121 -A -T4 # 得到开放端口22,80 在80端口得到save.zip&#xff0c;需要密码解压。 john破解压缩…

方案精读:71页制造企业一体化ERP系统项目实施方案【附全文阅读】

今天聊聊制造企业 ERP 系统项目实施方案。 某钾肥企业在发展中面临信息化难题,像物资编码不规范、业务手工化、财务业务脱节等 。为此,打造 “流程驱动,业务整合” 的一体化 ERP 管理平台很关键。它涵盖采购、销售、生产、运营流程,实现供应链、预算、资金、财务整…

MATLAB遇到内部问题,需要关闭,Crash Decoding : Disabled - No sandbox or build area path

1.故障界面 MATLAB运行时突然中断&#xff0c;停止运行。故障界面如图&#xff1a; MATLAB Log File: C:\Users\wei\AppData\Local\Temp\matlab_crash_dump.21720-1 ------------------------------------------------ MATLAB Log File -----------------------------------…

【Redis】Redis C++使用

一、Redis的自定义网络协议 1.1 为什么可以编写出一个自定义的Redis客户端 为什么我们可以编写出一个自定义的Redis客户端&#xff1f;因为Redis公开了自己的自定义协议。而对于一些其他软件的客户端&#xff0c;我们无法编写出一个自定义的Redis客户端&#xff0c;因为他们没…

每日一题(小白)暴力娱乐篇19

样例&#xff1a; 6 1 1 4 5 1 4 输出&#xff1a; 56 66 52 44 54 64 分析题意可以得知&#xff0c;就是接收一串数字&#xff0c;将数字按照下标每次向右移动一位&#xff08;末尾循环到第一位&#xff09;&#xff0c;每次移动玩计算一下下标和数字的乘积且累加。 ①接收…

25级总分413数学一142专业124东南大学820考研经验电子信息通信工程,真题,大纲,参考书。

我是南京理工大学的本科生&#xff0c;25 考研一战东大&#xff0c;政治 69&#xff0c;英一 78&#xff0c;数一 142&#xff0c;专业课&#xff08;820&#xff09;124&#xff0c;总分 413。我从 3 月正式开始备考&#xff0c;专业课跟着无线电论坛jenny 老师进行学习&#…

【数据结构_6上篇】有关链表的oj题

import java.util.*;/* public class ListNode {int val;ListNode next null;ListNode(int val) {this.val val;} }*/ public class Partition {public ListNode partition(ListNode pHead, int x) {// write code here//1.首先要判断链表是否为空的情况if(pHead null){retu…

【QT】QWidget 概述与核心属性(API)

&#x1f308; 个人主页&#xff1a;Zfox_ &#x1f525; 系列专栏&#xff1a;Qt 目录 一&#xff1a;&#x1f525; 控件概述 &#x1f98b; 控件体系的发展阶段 二&#xff1a;&#x1f525; QWidget 核心属性 &#x1f98b; 核心属性概览&#x1f98b; 用件可用&#xff08…

微服务篇——SpringCloud

服务注册 Spring Cloud5大组件有哪些&#xff1f; 服务注册和发现是什么意思&#xff1f;Spring Cloud如何实现服务注册发现&#xff1f; nacos与eureka的区别 负载均衡 如何实现负载均衡&#xff1f; Ribbon负载均衡的策略有哪些&#xff1f; 如何自定义负载均衡的策略&…

如何使用PyCharm自动化测试

如何使用PyCharm自动化测试 1.打开PyCharm右击文件&#xff0c;点击新建项目 按照如图配置&#xff0c;然后点击创建 2.创建好后&#xff0c;点击文件&#xff0c;然后点击设置 按照如图步骤&#xff0c;查看selenium和webdriver-manager是否存在 3.以上都完成后按照如图创…

记一次某网络安全比赛三阶段webserver应急响应解题过程

0X01 任务说明 0X02 靶机介绍 Webserver&#xff08;Web服务器&#xff09;是一种软件或硬件设备&#xff0c;用于接收、处理并响应来自客户端&#xff08;如浏览器&#xff09;的HTTP请求&#xff0c;提供网页、图片、视频等静态或动态内容&#xff0c;是互联网基础设施的核心…

复现QGIS-MCP教程

由于Claude国内下载不了尝试使用Cursor 下载安装Cursor Cursor - The AI Code Editor 本示例安装的是0.46版本 UV安装 简介 安装 安装成功 配置环境变量 验证 下载代码 git clone gitgithub.com:jjsantos01/qgis_mcp.git QGIS插件安装 文件拷贝 您需要将 qgis_mcp_plu…

docker部署certimateSSL证书管理自动续签

开源certimate项目地址&#xff1a;https://github.com/usual2970/certimate 官方文档地址&#xff1a;https://docs.certimate.me/docs/introduction 与certbot对比 维度CertbotCertimate安装方式通过包管理器&#xff08;如apt/yum&#xff09;安装支持二进制文件、Docker…

R语言——直方图

参考资料&#xff1a;学习R 如果我们要研究一个连续变量的分布&#xff0c;直方图是最佳的选择。 1、base绘图 在base中可以使用hist函数绘制直方图&#xff0c;与plot函数一样&#xff0c;它没有data参数&#xff0c;须把数据框置于with中。 data(obama_vs_mccain,package&q…

第4节:Python编程基础 - Python语法快速回顾

1. Python简介与环境配置 Python是一种高级、解释型、通用的编程语言&#xff0c;由Guido van Rossum于1991年首次发布。 它以简洁明了的语法和强大的功能而闻名&#xff0c;广泛应用于Web开发、数据分析、人工智能、科学计算等领域。 1.1 Python的特点 简单易学&#xff1a;…

十四、C++速通秘籍—函数式编程

目录 上一章节&#xff1a; 一、引言 一、函数式编程基础 三、Lambda 表达式 作用&#xff1a; Lambda 表达式捕获值的方式&#xff1a; 注意&#xff1a; 四、函数对象 函数对象与普通函数对比&#xff1a; 五、函数适配器 1、适配普通函数 2、适配 Lambda 表达式 …

博物馆小程序怎么做?从0到1打造数字化文化窗口

博物馆小程序怎么做&#xff1f;从0到1打造数字化文化窗口 一、行业痛点&#xff1a;传统博物馆的数字化困局 在数字化浪潮下&#xff0c;传统博物馆普遍面临三大挑战&#xff1a; ​​客流受限​​&#xff1a;线下接待能力有限&#xff0c;难以触达更广泛人群 ​​互动单一…