socket 客户端和服务器通信
服务器
using BarrageGrab;
using System;
using System.Collections.Concurrent;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;namespace Lyx {class Server{private TcpListener listener;private ConcurrentDictionary<TcpClient, DateTime> clients = new ConcurrentDictionary<TcpClient, DateTime>();private CancellationTokenSource cts = new CancellationTokenSource();public void Start(int port){listener = new TcpListener(IPAddress.Any, port);listener.Start();Console.WriteLine($"服务器已启动,监听端口 {port}...");new Thread(AcceptClients) { IsBackground = true }.Start();new Thread(CheckHeartbeats) { IsBackground = true }.Start();new Thread(HandleConsoleInput) { IsBackground = true }.Start();}private void AcceptClients(){try{while (!cts.Token.IsCancellationRequested){TcpClient client = listener.AcceptTcpClient();Console.WriteLine("新客户端连接:" + client.Client.RemoteEndPoint);clients.TryAdd(client, DateTime.Now);new Thread(() => HandleClient(client)) { IsBackground = true }.Start();}}catch (SocketException) { } // 监听器被停止时正常退出}private void HandleClient(TcpClient client){NetworkStream stream = null;try{stream = client.GetStream();byte[] buffer = new byte[1024];while (!cts.Token.IsCancellationRequested){int bytesRead;lock (client) // 同步网络流访问{if (!stream.DataAvailable){Thread.Sleep(100);continue;}bytesRead = stream.Read(buffer, 0, buffer.Length);}if (bytesRead <= 0) break;string message = Encoding.UTF8.GetString(buffer, 0, bytesRead);Console.WriteLine($"收到消息: {message}");if (message == "heartbeat"){clients.AddOrUpdate(client, DateTime.Now, (_, __) => DateTime.Now);SendMessage(client, "heartbeat");Logger.PrintColor($"服务器发送心跳: {message} ,给客户端成功:{client.Client.RemoteEndPoint}", ConsoleColor.Yellow);continue;}//SendMessage(client, "服务器收到: " + message);}}catch (Exception ex) { Console.WriteLine($"客户端错误: {ex.Message}"); }finally{if (client.Connected ){Console.WriteLine("客户端断开:" + client.Client.RemoteEndPoint);clients.TryRemove(client, out _);client.Close();stream?.Close();}}}public void BroadcastMessage(string message){byte[] data = Encoding.UTF8.GetBytes("服务器广播: " + message);foreach (var client in clients.Keys.ToArray()){try{lock (client){client.GetStream().Write(data, 0, data.Length);}}catch { }}Console.WriteLine("广播消息已发送");}public void SendMessage(TcpClient client, string message){if (!clients.ContainsKey(client)) return;byte[] data = Encoding.UTF8.GetBytes(message);try{lock (client) // 同步网络流访问{client.GetStream().Write(data, 0, data.Length);}Console.WriteLine($"消息发送成功 -> {client.Client.RemoteEndPoint}: {message}");}catch{Console.WriteLine("消息发送失败");}}private void HandleConsoleInput(){while (!cts.Token.IsCancellationRequested){string input = Console.ReadLine();if (input?.ToLower() == "exit"){Stop();break;}else if (!string.IsNullOrWhiteSpace(input)){BroadcastMessage(input);}}}private void CheckHeartbeats(){while (!cts.Token.IsCancellationRequested){Thread.Sleep(5000);DateTime now = DateTime.Now;foreach (var client in clients.Keys.ToArray()){if (clients.TryGetValue(client, out DateTime last) &&(now - last).TotalSeconds > 10){Console.WriteLine("客户端超时断开:" + client.Client.RemoteEndPoint);clients.TryRemove(client, out _);client.Close();}}}}public void Stop(){cts.Cancel();listener.Stop();foreach (var client in clients.Keys.ToArray()){client.Close();clients.TryRemove(client, out _);}Console.WriteLine("服务器已停止");}public void Main(){Server server = new Server();server.Start(54621);}}}
客户端
using System;
using System.Collections;
using System.Collections.Generic;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using UnityEngine;public class SocketClient : MonoBehaviour
{private TcpClient client;private NetworkStream stream;private Thread receiveThread;private bool isConnected = false;private string serverIP = "127.0.0.1"; // 服务器IP地址private int serverPort = 54621; // 服务器端口private float heartbeatTimeout = 5f; // 心跳超时时间private float heartbeatInterval = 0.5f; // 心跳发送间隔时间private float lastHeartbeatTime;private float lastSendHeartbeatTime;private bool updateHeartbeat = false; // 标志位,用于通知主线程更新心跳时间private int reconnectAttempts = 0; // 重连尝试次数private const int maxReconnectAttempts = 3; // 最大重连次数private const float reconnectInterval = 2f; // 重连间隔时间void Start(){ConnectToServer();}void Update(){// 检查是否需要更新心跳时间if (updateHeartbeat){lastHeartbeatTime = Time.time;updateHeartbeat = false;}// 检查心跳超时if (isConnected && Time.time - lastHeartbeatTime > heartbeatTimeout){Debug.Log("Heartbeat timeout, disconnecting...");Disconnect();}// 定时发送心跳消息if (isConnected && Time.time - lastSendHeartbeatTime > heartbeatInterval){SendData("heartbeat");lastSendHeartbeatTime = Time.time;}}void ConnectToServer(){try{client = new TcpClient(serverIP, serverPort);stream = client.GetStream();isConnected = true;lastHeartbeatTime = Time.time;lastSendHeartbeatTime = Time.time;reconnectAttempts = 0; // 重置重连尝试次数receiveThread = new Thread(new ThreadStart(ReceiveData));receiveThread.IsBackground = true;receiveThread.Start();Debug.Log("Connected to server.");}catch (Exception e){Debug.LogError("Error connecting to server: " + e.Message);TryReconnect();}}void ReceiveData(){byte[] buffer = new byte[1024];while (isConnected){try{int bytesRead = stream.Read(buffer, 0, buffer.Length);if (bytesRead > 0){string receivedMessage = Encoding.UTF8.GetString(buffer, 0, bytesRead);if (receivedMessage != null){Debug.Log("Received from server: " + receivedMessage);// 如果是心跳响应,通知主线程更新心跳时间if (receivedMessage.Equals("heartbeat")){updateHeartbeat = true;}}}}catch (Exception e){Debug.LogError("Error receiving data: " + e.Message);Disconnect();break;}}}public void SendData(string message){if (isConnected){try{byte[] data = Encoding.UTF8.GetBytes(message);stream.Write(data, 0, data.Length);Debug.Log("Sent to server: " + message);}catch (Exception e){Debug.LogError("Error sending data: " + e.Message);Disconnect();}}}void Disconnect(){if (isConnected){isConnected = false;if (receiveThread != null && receiveThread.IsAlive)receiveThread.Abort();if (stream != null)stream.Close();if (client != null)client.Close();Debug.Log("Disconnected from server.");// 尝试重连TryReconnect();}}void TryReconnect(){Debug.Log("触发重连机制");if (reconnectAttempts < maxReconnectAttempts){reconnectAttempts++;Debug.Log($"Attempting to reconnect ({reconnectAttempts}/{maxReconnectAttempts})...");Invoke("ConnectToServer", reconnectInterval); // 2秒后重连}else{Debug.Log("Max reconnection attempts reached. Giving up.");}}void OnDestroy(){Disconnect();}
}
相关文章:
socket 客户端和服务器通信
服务器 using BarrageGrab; using System; using System.Collections.Concurrent; using System.Linq; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading;namespace Lyx {class Server{private TcpListener listener;private Concurre…...
C实现md5功能
md5在线验证: 在线MD5计算_ip33.com 代码如下: #include "md5.h" #include <string.h> #include "stdio.h"/** 32-bit integer manipulation macros (little endian)*/ #ifndef GET_ULONG_LE #define GET_ULONG_LE(n,b,i) …...
【项目】CherrySudio配置MCP服务器
CherrySudio配置MCP服务器 (一)Cherry Studio介绍(二)MCP服务环境搭建(1)环境准备(2)依赖组件安装<1> Bun和UV安装 (3)MCP服务器使用<1> 搜索MCP…...
第五节:React Hooks进阶篇-如何用useMemo/useCallback优化性能
反模式:滥用导致的内存开销React 19编译器自动Memoization原理 React Hooks 性能优化进阶:从手动到自动 Memoization (基于 React 18 及以下版本,结合 React 19 新特性分析) 一、useMemo/useCallback 的正确使用场景…...
【Qt】QWidget 核⼼属性详解
🍑个人主页:Jupiter. 🚀 所属专栏:QT 欢迎大家点赞收藏评论😊 目录 🏝 一.相关概念🎨二. 核⼼属性概览🍄2.1 enabled🥭2.2geometry🌸 2.3 windowTitle&#…...
如何知道raid 有问题了
在 Rocky Linux 8 上,你的服务器使用了 RAID5(根据 lsblk 输出,/dev/sda3、/dev/sdb1 和 /dev/sdc1 组成 md127 RAID5 阵列)。为了监控 RAID5 阵列中磁盘的健康状态,并及时发现某块磁盘损坏,可以通过以下方…...
操作系统之shell实现(上)
🌟 各位看官好,我是maomi_9526! 🌍 种一棵树最好是十年前,其次是现在! 🚀 今天来学习C语言的相关知识。 👍 如果觉得这篇文章有帮助,欢迎您一键三连,分享给更…...
精益数据分析(3/126):用数据驱动企业发展的深度解析
精益数据分析(3/126):用数据驱动企业发展的深度解析 大家好!一直以来,我都坚信在当今竞争激烈的商业环境中,数据是企业获得竞争优势的关键。最近深入研究《精益数据分析》这本书,收获颇丰&…...
React 18/19 使用Ant Design全局弹窗message
react 18 及以上,拥有并发模式,不允许在渲染过程中直接触发副作用(如弹窗、网络请求等),应将其放至 useEffect 中,确保其在渲染完成后调用 useEffect(() > {message.success(操作成功!);}, …...
【spark3.2.4】--完全分布式集群搭建
一、spark-env.sh 文件配置(操作路径:$SPARK_HOME/conf/spark-env.sh) 如果还没创建: cp $SPARK_HOME/conf/spark-env.sh.template $SPARK_HOME/conf/spark-env.sh然后编辑(比如用 vim): vim…...
Web3技术下数字资产数据保护的实践探索
在这个信息爆炸的时代,数字资产已经成为我们生活中不可或缺的一部分。随着Web3技术的兴起,它以其去中心化、透明性和安全性的特点,为数字资产的管理和保护提供了新的解决方案。本文将探讨Web3技术在数字资产数据保护方面的实践探索࿰…...
灰度共生矩阵(GLCM)简介
灰度共生矩阵(GLCM)简介 1. 基本概念 灰度共生矩阵(Gray-level Co-occurrence Matrix, GLCM)是一种用于分析图像纹理特征的统计方法。它通过计算图像中特定空间关系的像素对出现的频率,来描述纹理的规律性1。 核心思想:统计图像中相距为d、方向为θ的两个像素点,分别具…...
基于javaEE+jqueryEasyUi+eclipseLink+MySQL的课程设计客房管理信息系统
1. 系统概述 1.1 系统功能概述 1)客户管理。能够增加一个客户,包括:身份证号、客户名称、出生年月、性别、联系电话、邮箱、会员类别等信息,默认会员类别为空;能够修改和删除客户信息;能够根据客户名称、联系电话查询…...
3款本周高潜力开源AI工具(多模态集成_隐私本地化)
本周聚焦 AI 技术领域,为开发者精选 3 款兼具创新性与实用性的开源项目。这些项目覆盖图像生成、智能助手、大语言模型框架等方向,通过技术突破解决开发痛点,助力开发者高效构建智能应用。 更多精彩科技推荐请点击->:更多精彩科…...
第一期第10讲
Linux常用的压缩文件扩展名有 .tar, .tar.bz2, .tar.gz 使用gzip压缩和解压缩 对单个文件压缩: gzip a.c //压缩a.c为a.c.gz gzip -d a.c.gz //解压缩为a.c 对文件夹压缩: gzip -r test //对test文件夹里的文件进行压缩,不对test进行压缩…...
计算方法在单细胞数据分析中的应用及AI拓展
单细胞技术的出现彻底革新了我们对生物系统的理解,揭示了看似同质的细胞群体内部复杂的异质性。为了从这些技术产生的大量复杂数据中提取有意义的见解,精密的计算方法是不可或缺的。 AI拓展 单细胞数据分析的核心在于处理和解释高维度数据的能力&#…...
如何配置环境变量HADOOP_HOMEM、AVEN_HOME?不配置会怎么样
以下是在不同操作系统中配置 HADOOP_HOME 和 JAVA_HOME 环境变量的方法,以及不配置可能产生的后果: 配置 HADOOP_HOME - Windows系统:下载并解压Hadoop安装包,然后右键“此电脑”,选择“属性”,点击“高级…...
【现代深度学习技术】循环神经网络03:语言模型和数据集
【作者主页】Francek Chen 【专栏介绍】 ⌈ ⌈ ⌈PyTorch深度学习 ⌋ ⌋ ⌋ 深度学习 (DL, Deep Learning) 特指基于深层神经网络模型和方法的机器学习。它是在统计机器学习、人工神经网络等算法模型基础上,结合当代大数据和大算力的发展而发展出来的。深度学习最重…...
【学习笔记】Taming 3DGS泛读
原文链接:https://arxiv.org/abs/2406.15643 代码链接:https://github.com/nullptr81/3dgs-accel 一、学习内容 1.研究背景 3DGS在新视角合成(NVS)中表现优异,但优化过程低效: 存在 1)资源需…...
SAP系统交货已完成标识
问题:交货已完成标识 现象:采购订单一直处于未完成交货状态,及交货完成标识处于非勾选状态 原因:采购订单交货完成标识勾会在两种情况下勾选, a.交货数量在容差范围内; b.手动勾选。 某些特殊情况…...
【正点原子STM32MP257连载】第四章 ATK-DLMP257B功能测试——音频测试 #ES8388 #录音测试
1)实验平台:正点原子ATK-DLMP257B开发板 2)浏览产品:https://www.alientek.com/Product_Details/135.html 3)全套实验源码手册视频下载:正点原子资料下载中心 文章目录 第四章 ATK-DLMP257B功能测试——音频…...
WPF 使用 DI EF CORE SQLITE
WPF 使用 DI EF CORE SQLITE 1.安装 nuget包 <PackageReference Include"Microsoft.EntityFrameworkCore.Sqlite" Version"9.0.4" />2.创建DbContext的实现类,创建有参构造函数 public XXContext(DbContextOptions<XXXContext> o…...
探索鸿蒙沉浸式:打造无界交互体验
一、鸿蒙沉浸式简介 在鸿蒙系统中,沉浸式是一种极具特色的设计理念,它致力于让用户在使用应用时能够全身心投入到内容本身,而尽可能减少被系统界面元素的干扰。通常来说,就是将应用的内容区巧妙地延伸到状态栏和导航栏所在的界面…...
Linux红帽:RHCSA认证知识讲解(十 三)在serverb上破解root密码
Linux红帽:RHCSA认证知识讲解(十 三)在serverb上破解root密码 前言操作步骤 前言 在红帽 Linux 系统的管理工作中,系统管理员可能会遇到需要重置 root 密码的情况。本文将详细介绍如何通过救援模式进入系统并重新设置 root 密码。…...
【网络安全】谁入侵了我的调制解调器?(一)
文章目录 我被黑了159.65.76.209,你是谁?黑客攻击黑客?交出证据三年后我被黑了 两年前,在我家里使用家庭网络远程办公时,遇到了一件非常诡异的事情。当时,我正在利用一个“盲 XXE 漏洞”,这个漏洞需要借助一个外部 HTTP 服务器来“走私”文件。为了实现这一点,我在 AW…...
阿里一面:Nacos配置中心交互模型是 push 还是 pull ?(原理+源码分析)
对于Nacos大家应该都不太陌生,出身阿里名声在外,能做动态服务发现、配置管理,非常好用的一个工具。然而这样的技术用的人越多面试被问的概率也就越大,如果只停留在使用层面,那面试可能要吃大亏。 比如我们今天要讨论的…...
MySQL 慢查询日志深入分析与工具实战(mysqldumpslow pt-query-digest)
🎯 学习目标 • ✅ 熟悉慢查询日志结构与核心字段 • ✅ 掌握日志开启与 SQL 记录机制 • ✅ 使用 pt-query-digest 工具进行分析 • ✅ 解读分析结果并提出优化建议 📂 基本概念 项目 内容说明 功能 记录执行时间超过阈值的 SQL 启动参数…...
JVM:垃圾回收
一、垃圾回收概述 (1)垃圾回收主要解决的问题 内存溢出:当程序在运行过程中,所需的内存超出了 JVM 被分配到的内存空间时,就会发生内存溢出。垃圾回收会将不再被引用的对象进行回收,释放内存空间…...
与AI深度融合的Go开发框架sponge,解决使用cursor、trae等AI辅助编程工具开发项目时的部分痛点
摘要 AI 编程助手在近几年快速发展,帮助开发者提升了开发效率。然而,通用 AI 工具往往难以精准落地到具体业务与框架中。本文介绍了一款与 Go 框架深度融合的 AI 编程工具 —— sponge AI 助手。它不仅理解框架的结构,还能按照标准化流程自动…...
《AI大模型应知应会100篇》第21篇:Prompt设计原则:让大模型精准理解你的需求
第21篇:Prompt设计原则:让大模型精准理解你的需求 摘要 在与大模型交互时,如何高效地表达需求是决定输出质量的关键。本文将系统介绍高效Prompt设计的核心原则和方法论,并通过实战代码案例详细解释每个核心知识点,帮助…...
【更新完毕】2025泰迪杯数据挖掘竞赛A题数学建模思路代码文章教学:竞赛论文初步筛选系统
完整内容请看文末最后的推广群 基于自然语言处理的竞赛论文初步筛选系统 基于多模态分析的竞赛论文自动筛选与重复检测模型 摘要 随着大学生竞赛规模的不断扩大,参赛论文的数量激增,传统的人工筛选方法面临着工作量大、效率低且容易出错的问题。因此&…...
[Windows] 电脑自动备份插入的U盘数据
[Windows] 电脑自动备份U盘数据 链接:https://pan.xunlei.com/s/VONyazSEIqhnzZCHRlio9Vw2A1?pwdcmhc# [Windows] 电脑自动备份插入的U盘数据...
《JVM考古现场(二十一):奇点黎明·在事件视界编译时空曲率》
目录 楔子:事件视界警报 上卷时空曲率引擎 第一章:volatile场方程重构 第二章:synchronized黑洞能层 番外篇:时空涟漪观测站 中卷量子逃逸分析 第三章:柯西视界稳定性证明 第四章:白洞负熵连接 实战…...
list的一些常用接口
其实list的接口和前面的string和vector基本都是一样的,用法也基本类似,我们还是挑几个讲讲吧。 一.常用的接口 1.1 push_back 图中是一个空参构造加上一个push_back的使用,这两个接口的使用还是很简单的,看一下即可。下面是迭代器…...
芯洲SCT2434AQFPAR:3.6V-36V Vin, 3.5A, 高效率同步降压DCDC转换器
特性: AEC-Q100合格,结果如下:-器件温度等级1:-40C至125C环境工作温度范围宽输入电压范围:3.6V-36V持续输出电流3.5A 1V1%反馈参考电压集成60mΩ高侧功率MOSFET和36mΩ低侧功率MOSFET轻载PSM工作模式在睡眠模式下具有…...
单例模式:懒汉和饿汉
目录 一、关于设计模式 二、单例模式是什么 2.1 饿汉模式 2.2 懒汉模式 三、单例模式和多线程 3.1 饿汉模式 3.2 懒汉模式 一、关于设计模式 单例模式是一种设计模式,说它之前先来聊聊设计模式是什么。 设计模式,类似于于棋谱(大佬把…...
第八节:React HooksReact 18+新特性-React Server Components (RSC) 工作原理
• 与SSR区别:零客户端JS、服务端数据直出 • 搭配Next.js 14使用场景 React Server Components (RSC) 工作原理及 Next.js 14 应用场景解析 一、RSC 核心工作原理 React Server Components (RSC) 是 React 18 引入的颠覆性特性,其设计目标是 服务端与…...
Spark-SQL核心编程3
数据加载与保存 通用方式: SparkSQL 提供了通用的保存数据和数据加载的方式。这里的通用指的是使用相同的API,根据不同的参数读取和保存不同格式的数据,SparkSQL 默认读取和保存的文件格式为parquet 数据加载方法: spark.read.lo…...
利用XShell 创建隧道(tunnel)在本地可视化远程服务器上的Visdom
1. 创建隧道 打开Xshell,选择你想要操作的终端,单击右键 -> 选择属性 打开属性对话框后,单击添加按钮。 在弹出的对话框中,先填写自己本地的浏览器的地址以及对应的端口号。然后呢,再填写autod远程服务器的地址和…...
React 高级特性与最佳实践
在掌握了 React 的基础知识后,我们可以进一步探索 React 的高级特性和最佳实践。这些特性将帮助你构建更高效、可维护和可扩展的 React 应用。本文重点介绍 Hooks、Context、Refs 和高阶组件等核心高级特性。 1. Hooks:函数组件的强大工具 Hooks 是 Rea…...
考研数据结构之图(一)(包含真题及解析)
考研数据结构之图的存储与基本操作:邻接矩阵、邻接表、十字链表、邻接多重表 图(Graph)是数据结构中的重要非线性结构,广泛应用于网络路由、社交关系分析等领域。本文将详细讲解图的四种主要存储方式——邻接矩阵法、邻接表法、十…...
Qt QML实现Windows桌面颜色提取器
前言 实现一个简单的小工具,使用Qt QML实现Windows桌面颜色提取器,实时显示鼠标移动位置的颜色值,包括十六进制值和RGB值。该功能在实际应用中比较常见,比如截图的时候,鼠标移动就会在鼠标位置实时显示坐标和颜色值&a…...
2025 年网络安全的挑战与机遇
2024 年是网络安全领域风云变幻的一年。从备受瞩目的勒索软件攻击所带来的影响,到人工智能工具日益商品化,挑战不断增加。 关键基础设施的漏洞变得极为明显,身份盗窃次数也达到了前所未有的程度。然而,在这一片混乱之中ÿ…...
Vue 3 中 ref和reactive的详细使用场景
一、核心区别 特性refreactive数据类型基本类型 对象/数组(自动解包)仅对象/数组响应式原理通过 .value 触发响应直接代理对象模板中使用自动解包(无需 .value)直接访问属性解构/传递保持响应性需用 toRefs 保持响应性 二、使用…...
react使用createFromIconfontCN,自定义iconfont 图标
记录reactantdesign项目中使用createFromIconfontCN,自定义iconfont 图标 效果图: import { createFromIconfontCN } from ant-design/icons;const MyIcon createFromIconfontCN({scriptUrl: //at.alicdn.com/t/font_8d5l8fzk5b87iudi.js, // 在 icon…...
危化品经营单位安全生产管理人员备考要点
危化品经营单位安全生产管理人员备考要点 📌 考试核心内容 ✅ 必考法规: 《危险化学品安全管理条例》重点条款(如经营许可条件) GB 18218-2018《重大危险源辨识》新标准 安全生产法律责任(罚款金额/刑事责任&…...
音频炼金术:Threejs 让 3D 场景「听」起来更真实
在 Three.js 中允许在场景中添加声音,将声音与 3D 对象关联,实现更丰富的交互体验。 Audio Three.js 中的Audio对象用于表示音频源,它是一个THREE.Object3D的子类,用于控制音频播放、暂停、是否循环等设置的对象,可以…...
【C++】Stack和Queue的底层封装和实现
目录 stack容器适配器stack的模拟实现 queue的模拟实现deque了解deque的结构deque的管理方式和遍历元素方式deque的缺陷为啥库里面的stack和queue使用deque end stack 容器适配器 Stack可以封装成前面三个变量的形式,但是这里我们提出一个概念叫容器适配器…...
Vue3 SSR 工程化实践:日常工作中的性能优化与实战技巧
一、流式渲染与分块传输(面向性能的关键优化) 1.1 流式响应基础实现 // Node.js Express 示例(Vite SSR同理)import { renderToWebStream } from vue/server-rendererapp.get(/, async (req, res) > { res.setHeader(Conten…...
【Python进阶】字符串操作全解与高效应用
目录 前言:技术背景与价值当前技术痛点解决方案概述目标读者说明 一、技术原理剖析核心概念图解核心作用讲解关键技术模块技术选型对比 二、实战演示环境配置要求核心代码实现(10个案例)案例1:基础操作案例2:高效格式化…...