.net中用标志位解决socket粘包问题

news/2024/2/20 22:54:29

以下为wpf中, 用标志位"q" 解决粘包问题

using MyFrameWorkWpf.Entities;
using System.Collections.ObjectModel;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Controls;namespace MyFrameWorkWpf.ViewModels
{public partial class TcpServerViewModel : ObservableObject{public TcpServerViewModel(){myIp = "192.168.2.100";myPort = "8888";}//声明一个Socket对象private Socket socketServer = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);private CancellationTokenSource cts = new();private ManualResetEvent resetEvent = new ManualResetEvent(true);private static readonly object lockObj = new object(); // 创建一个对象作为锁private readonly MyRArr myRArr;//创建字典集合,键是ClientIp,值是SocketClientprivate Dictionary<string, Socket> currentClientlist = new Dictionary<string, Socket>();private ObservableCollection<string> serverList = new();public ObservableCollection<string> ServerList{get => serverList;set => SetProperty(ref serverList, value);}private string myIp = "";public string MyIp{get => myIp;set => SetProperty(ref myIp, value);}private string myPort = "";public string MyPort{get => myPort;set => SetProperty(ref myPort, value);}private ObservableCollection<TcpMessage> reciveData = new();public ObservableCollection<TcpMessage> ReciveData{get => reciveData;set => SetProperty(ref reciveData, value);}private string sendTxt = "";public string SendTxt{get => myPort;set => SetProperty(ref myPort, value);}private bool isEnabled = true;public bool IsEnable{get => isEnabled;set => SetProperty(ref isEnabled, value);}public RelayCommand<RadioButton> SelectView { get; private set; }//public RelayCommand<Button> ConnCommand => new RelayCommand<Button>((args) =>//{//    if (!(args is Button button)) return;//});public RelayCommand<Button> ConnCommand =>new RelayCommand<Button>((args) =>{if (!(args is Button button)) return;if (MyIp != null && MyPort != null){IPEndPoint ipe = new IPEndPoint(IPAddress.Parse(MyIp), int.Parse(this.MyPort));try{socketServer.Bind(ipe);}catch (Exception ex){MessageBox.Show(ex.Message);return;}MessageBox.Show("服务器开启成功");button.IsEnabled = false;//IsEnabled = false;//只监听一个socketServer.Listen(1);//创建一个监听的线程Task.Run(new Action(async () =>{while (!cts.IsCancellationRequested){// 第四步:调用accept()函数来接受客户端的连接,这是就可以和客户端通信了。Socket? socketClient = socketServer.Accept();string? client = socketClient?.RemoteEndPoint?.ToString();if (socketClient != null && client != null){currentClientlist.Add(client, socketClient);Application.Current.Dispatcher.Invoke(() =>{ServerList.Add(client);});await Task.Delay(500);// 创建一个缓冲区while (!cts.IsCancellationRequested){byte[] buffer = new byte[1024 * 1024 * 10];int length = -1;// 第五步:处理客户端的连接请求。try{//length = socketClient.ReceiveFrom(buffer, 0, 8192, SocketFlags.None, ref remoteEP);if (ServerList.Count > 0){length = currentClientlist[ServerList[0]].Receive(buffer);}}catch (Exception ex){ServerList.Remove(client);currentClientlist.Remove(client);MessageBox.Show(ex.Message);break;}if (length > 0){byte[] temp = new byte[length];//buffer复制到tempArray.Copy(buffer, 0, temp, 0, length);byte[] separator = Encoding.UTF8.GetBytes("q");//q所在的索引位置int idx = Array.IndexOf(buffer, separator[0], 0, length);if (idx >= 0){var data = Encoding.ASCII.GetString(temp);var res = data.Substring(0, idx); //截取索引之前的数据TcpMessage tcpMessage = new();lock (lockObj){tcpMessage.DateTime = DateTime.Now;tcpMessage.Message = res;tcpMessage.Client = ServerList[0];}Application.Current.Dispatcher.Invoke(() =>{ReciveData.Add(tcpMessage);});}//string msg = string.Empty;//msg = Encoding.ASCII.GetString(buffer, 0, length);//TcpMessage tcpMessage = new();//lock (lockObj)//{//    tcpMessage.DateTime = DateTime.Now;//    tcpMessage.Message = msg;//    tcpMessage.Client = ServerList[0];//}//Application.Current.Dispatcher.Invoke(() =>//{//    ReciveData.Add(tcpMessage);//});}}}}}),cts.Token);}else{MessageBox.Show("Ip,端口号不能为空!");}});public RelayCommand DisConnCommand => new RelayCommand(() => { });public RelayCommand SendMsgCommand =>new RelayCommand(() =>{byte[] send = Encoding.ASCII.GetBytes(SendTxt);//创建最终发送的数组byte[] sendMsg = new byte[send.Length];//整体拷贝数组Array.Copy(send, 0, sendMsg, 0, send.Length);if (ServerList.Count > 0){string client = ServerList[0];currentClientlist[client]?.Send(sendMsg);}SendTxt = string.Empty;});public RelayCommand EditCommand => new RelayCommand(() => { });}
}

http://www.ppmy.cn/news/1142890.html

相关文章

分享购商业模式解析:三个角色、排位机制、奖励机制

分享购是一个自循环商业模式&#xff0c;它通过将第三方平台&#xff08;如京东、天猫、淘宝等&#xff09;的优惠券和折扣等信息整合到自营商城中&#xff0c;并合理分配给用户或消费者&#xff0c;增强了用户黏性&#xff0c;实现了持续多次的变现。分享购的核心机制是其排位…

Java每日笔试题错题分析(1)

Java每日笔试题错题分析&#xff08;1&#xff09; 一、错题知识点前瞻第26题第29题第34题第41题第50题 二、错题展示及其解析第26题第29题第34题第41题第50题 一、错题知识点前瞻 第26题 多个catch块中子类异常放在前面&#xff0c;父类异常放在后面&#xff0c;否则会产生编…

python 的全局变量与 global的说明

在python中&#xff0c;在函数外部定义的变量是全局变量。 全局变量可以在函数内部引用。 g_var 1def test():print(g_var)在函数内部引用全局变量&#xff0c;如果不修改&#xff0c;可以不用 global 关键字声明。以上代码&#xff0c;因为在 test 函数内部&#xff0c;g_v…

10_8C++

X-Mind #include <iostream>using namespace std; class Rect { private:int width;int heigjt; public:void init(int w,int h){width w;heigjt h;}void set_w(int w){width w;}void set_h(int h){heigjt h;}void show(){cout << "矩形的周长" <…

【c#】线程Monitor.Wait和Monitor.Pulse使用

介绍 以一个简易版的数据库连接池的实现来说明一下 连接池的connection以队列来管理 getConnection的时候&#xff0c;如果队列中connection个数小于50&#xff0c;且暂时无可用的connection&#xff08;个数为0或者peek看下头部需要先出那个元素还处于不可用状态&#xff09;…

2023年失业了,想学一门技术可以学什么?

有一个朋友&#xff0c;大厂毕业了&#xff0c;原本月薪估计有5w吧&#xff0c;年终奖也不错&#xff0c;所以早早的就买了房生了娃&#xff0c;一直是人生赢家的姿态。 但是今年突然就被毕业了&#xff0c;比起房货还有个几百万没还来说&#xff0c;他最想不通的是自己的价值…

二次封装View Design的table组件,实现宽度自适应,内容在一行展示

由于table组件本身并不支持宽度自适应&#xff0c;但实际项目需要&#xff0c;而且多处有用到table组件&#xff0c;所以尝试着自己来二次封装一下组件 想法 刚开始的想法很简单&#xff0c;就是获取每一列中数据和标题在表格中的长度&#xff0c;然后将当中最大的长度作为该列…

NEFU数字图像处理(2)图像增强

一、背景 图像在传输或处理过程中会引入噪声或使图像变模糊&#xff0c;从而降低了图像质量&#xff0c;甚至淹没了特征给分析带来困难&#xff0c;因此要增强特征&#xff0c;进行处理 图像增强按特定的需要突出一幅图像中的某些信息同时&#xff0c;削弱或去除某些不需要的信…

Opencv中!face_cascade.load( face_cascade_name )报错,xml文件无法加载

face_cascade.load 在opencv中加载xml文件的代码片段如下 // 代码片段cv::String face_cascade_name "D:/opencv2.49/opencv/sources/data/haarcascades/haarcascade_eye_tree_eyeglasses.xml";if (!face_cascade.load(face_cascade_name)){ printf("--(!)Er…

docker入门加实战—docker安装并配置阿里云加速

docker入门加实战—docker安装并配置阿里云加速 为什么要学习docker 在开发和部署项目的过程中&#xff0c;经常会遇到如下问题&#xff1a; 软件安装包名字复杂&#xff0c;不知道去哪里找安装软件和部署项目步骤复杂&#xff0c;容易出错 这就是我们今天要学习Docker技术…

C++基础知识3

1、为什么构造函数不能是虚构造&#xff1f; 虚函数对应一个虚表vtale&#xff0c;这个表的地址是存储在对象的内存空间的。如果将构造函数设置为虚函数&#xff0c;就需要到虚表中调用&#xff0c;但这时候对象没有实例化&#xff0c;没有内存分配&#xff0c;虚表就不存在&am…

java多线程卖电影票的三种实现方式

java多线程卖电影票的三种实现方式 一、需求描述二、实现方式1、继承Thread类的方式2、实现Runnable接口的方式3、使用Lock锁的方式 一、需求描述 某电影院目前正在上映国产大片&#xff0c;共有1000张票&#xff0c;而它有2个窗口卖票&#xff0c;请设计一个程序模拟该电影院…

Flex 布局中避免子元素高度被撑高

Flex 布局中避免子元素高度被撑高 Flex 布局中子元素高度容易被最高元素撑高&#xff0c;使用 align-self 可避免。 之前&#xff1a; 之后&#xff1a; /* 此处是居中对齐&#xff0c;也可使用 flex-start 顶部对齐 */ align-self: center;

在MySQL中使用!=还能走索引吗?

在MySQL中使用!还能走索引吗&#xff1f; 一般情况下&#xff0c;我们会在一个索引上较多的使用等值查询或者范围查询&#xff0c;此时索引大多可以帮助我们极快的查询出我们需要的数据。 那当我们在where条件中对索引列使用!查询&#xff0c;索引还能发挥他的作用吗&#xf…

Spring如何更简易的存储(注解)和读取Bean对象?

目录 1.存储Bean对象 1.1 添加注解的前提 &#xff08;添加配置&#xff09; 1.2 使用Spring注解存储Bean对象 1.2.1实例&#xff1a;Controller(控制器存储)的使用 Bean对象&#xff1a; 启动类MainApp 执行结果 一些由于命名引发的问题&#xff08;适用于五大类注解&#xff…

【yaml文件的编写】

yaml文件编写 YAML语法格式写一个yaml文件demo创建资源对象查看创建的pod资源创建service服务对外提供访问并测试创建资源对象查看创建的service在浏览器输入 nodeIP:nodePort 即可访问 详解k8s中的port&#xff1a;portnodePorttargetPortcontainerPortkubectl run --dry-runc…

【C++】面向对象编程(五)初始化、复制、析构

初始化 基类数据成员初始化 如果基类有了实际的数据成员&#xff0c;则我们必须给基类数据成员初始化&#xff1a;为基类提供构造函数&#xff08;利用这个构造函数初始化基类所声明的所有数据成员&#xff09; 注意&#xff1a;抽象基类无法定义任何对象&#xff08;因为抽…

JVM222

文章目录 JVM222运行时数据区的内部结构线程程序计数器&#xff08;PC寄存器&#xff09;虚拟机栈 JVM222 运行时数据区的内部结构 概述 本节主要讲的是运行时数据区&#xff0c;也就是下图这部分&#xff0c;它是在类加载器加载完成后的阶段&#xff0c;如下图&#xff1a; …

Java自动化测试的分类

Java自动化测试分为单元测试和验收测试&#xff0c;验收测试按测试目标又分为web测试、移动端测试。 一、单元测试 单元测试&#xff08;unit testing&#xff09;&#xff0c;是指对软件中的最小可测试单元进行检查和验证。对于单元测试中单元的含义&#xff0c;一般来说&am…

nacos2.0.2漏洞分析及解决方法

绕过鉴权情况 1. userAgentAuthWhite 设置为true&#xff0c;官方没有还没有解析为啥可以通过设置userAgent可以绕过鉴权 实验一 只要把请求header&#xff1a;User-Agent设置为&#xff1a;Nacos-Server&#xff0c;即可绕过鉴权 实验二 只要把请求header&#xff1a;User…
最新文章