当前位置: 首页 > news >正文

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

以下为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.lryc.cn/news/186707.html

相关文章:

  • 【Ubuntu】Systemctl 管理 MinIO 服务器的启动和停止
  • 《golang设计模式》第二部分·结构型模式-07-代理模式(Proxy)
  • Jmeter常用线程组设置策略
  • 【Spring】Spring MVC 程序开发
  • 如何在企业网站里做好网络安全
  • windows server 2012 服务器打开系统远程功能
  • 智能工厂MES系统,终端设备支持手机、PDA、工业平板、PC
  • GPT的优势和GPT缺点
  • 微信小程序开发缺少中间证书问题(腾讯云、阿里云等做服务器)
  • 动态代理初步了解
  • QT国际化
  • 微信小程序button按钮去除边框去除背景色
  • Neo4j深度学习
  • 【数据结构C/C++】链式存储与顺序存储结构栈
  • 【数据库系统概论】数据定义之基本表的定义/创建、修改和删除
  • 面试算法22:链表中环的入口节点(1)
  • 蓝桥杯---第二讲---二分与前缀和
  • d3dx9_39.dll如何修复?最新修复d3dx9_39.dll方法分享
  • 阿里云轻量应用服务器月流量限制说明(部分套餐不限流量)
  • 项目设计:YOLOv5目标检测+机构光相机(intel d455和d435i)测距
  • WPF中DataContext的绑定技巧
  • 【Spring MVC研究】MVC原理:DispatcherServlet的初始化,初始化好等于MVC准备好
  • Kafka的分布式架构与高可用性
  • Spring Cloud学习笔记【分布式请求链路跟踪-Sleuth】
  • Java开发中的操作日志详解(InsCode AI 创作助手)
  • FutureTask和CompletableFuture的模拟使用
  • Redis作为缓存,mysql的数据如何与redis进行同步?
  • 申请免费 SSL 证书为您的小程序加密通信
  • Go 并发编程
  • 鱼眼相机去畸变(图像拉直/展开/矫正)算法及实战总结