| using System.Net; |
| using System.Net.Sockets; |
| using System.Runtime.InteropServices; |
| |
| namespace Seer.SeerSocket; |
| public struct SeerMessageHead |
| { |
| public byte sync; |
| public byte version; |
| public ushort number; |
| public uint length; |
| public ushort type; |
| |
| #pragma warning disable 0414 //禁用警告 |
| #pragma warning disable 0169 //禁用警告 |
| private readonly byte ref0; |
| private readonly byte ref1; |
| private readonly byte ref2; |
| private readonly byte ref3; |
| private readonly byte ref4; |
| private readonly byte ref5; |
| #pragma warning restore 0414 //恢复警告 |
| #pragma warning restore 0169 //恢复警告 |
| |
| |
| public SeerMessageHead() |
| { |
| this.sync = 0x5A; |
| this.version = 0x01; |
| this.number = 0x0001; |
| } |
| public SeerMessageHead(ushort type) |
| { |
| this.type = type; |
| } |
| |
| |
| |
| |
| |
| public readonly byte[] ToBytes() |
| { |
| |
| int size = Marshal.SizeOf(this); |
| byte[] bytes = new byte[size]; |
| |
| IntPtr ptr = Marshal.AllocHGlobal(size); |
| Marshal.StructureToPtr(this, ptr, true); |
| Marshal.Copy(ptr, bytes, 0, size); |
| Marshal.FreeHGlobal(ptr); |
| |
| if (BitConverter.IsLittleEndian) |
| { |
| Array.Reverse(bytes, 2, 2); |
| Array.Reverse(bytes, 4, 4); |
| Array.Reverse(bytes, 8, 2); |
| } |
| return bytes; |
| |
| } |
| |
| |
| }; |
| |
| |
| |
| public class SeerSocket |
| { |
| private const string IpAddress = "127.0.0.1"; |
| private readonly Dictionary<int, TcpClient> clients; |
| |
| public SeerSocket(bool onlyRead = true) |
| { |
| this.clients = new Dictionary<int, TcpClient> |
| { |
| { 19204, new TcpClient(IpAddress, 19204) } |
| }; |
| if (onlyRead) return; |
| this.clients.Add(19205, new TcpClient(IpAddress, 19205)); |
| this.clients.Add(19206, new TcpClient(IpAddress, 19206)); |
| this.clients.Add(19207, new TcpClient(IpAddress, 19207)); |
| this.clients.Add(19210, new TcpClient(IpAddress, 19210)); |
| } |
| |
| |
| private TcpClient GetClient(int port) |
| { |
| return clients[port]; |
| } |
| |
| |
| public string Send(ushort type, string msg = "", int port = 19204) |
| { |
| var msgBody = NormalStrToHexByte(msg); |
| var msgHead = CreateMsgHead(type, (uint)msgBody.Length); |
| var response = this.SendRaw(msgHead, msgBody, port); |
| return response; |
| } |
| |
| private string SendRaw(byte[] msgHead, byte[] msgBody, int port) |
| { |
| try |
| { |
| TcpClient client = this.GetClient(port); |
| if (!client.Connected) |
| { |
| this.clients[port] = new TcpClient(IpAddress, port); |
| Console.WriteLine($"{IpAddress}:{port}:断开连接"); |
| return "fail"; |
| } |
| |
| NetworkStream serverStream = client.GetStream(); |
| serverStream.Write(msgHead, 0, msgHead.Length); |
| serverStream.Write(msgBody, 0, msgBody.Length); |
| serverStream.Flush(); |
| |
| byte[] inStream = new byte[16]; |
| while (16 != serverStream.Read(inStream, 0, 16)) |
| { |
| Thread.Sleep(20); |
| } |
| var recv_head = BytesToStructure<SeerMessageHead>(inStream); |
| byte[] recvbyte = BitConverter.GetBytes(recv_head.length); |
| Array.Reverse(recvbyte); |
| |
| var dsize = BitConverter.ToUInt32(recvbyte, 0); |
| const int bufferSize = 512; |
| List<byte> datalist = new List<byte>(); |
| int count = 0; |
| while (true) |
| { |
| byte[] buffer = new byte[bufferSize]; |
| int readSize = serverStream.Read(buffer, 0, bufferSize); |
| count += readSize; |
| datalist.AddRange(buffer); |
| if (count == dsize) |
| { |
| break; |
| } |
| } |
| |
| |
| string resMsg = System.Text.Encoding.UTF8.GetString(datalist.ToArray()); |
| return resMsg; |
| } |
| catch (SocketException) |
| { |
| return "fail"; |
| } |
| catch (IOException) |
| { |
| return "fail"; |
| } |
| } |
| |
| public void CloseAll(){ |
| foreach(var client in this.clients.Values){ |
| client.Close(); |
| } |
| } |
| |
| private T BytesToStructure<T>(byte[] bytesBuffer) |
| { |
| if (bytesBuffer.Length < Marshal.SizeOf(typeof(T))) |
| { |
| throw new ArgumentException("size error"); |
| } |
| |
| nint bufferHandler = Marshal.AllocHGlobal(bytesBuffer.Length); |
| |
| for (int index = 0; index < bytesBuffer.Length; index++) |
| { |
| Marshal.WriteByte(bufferHandler, index, bytesBuffer[index]); |
| } |
| |
| |
| T? structObject = Marshal.PtrToStructure<T>(bufferHandler); |
| |
| Marshal.FreeHGlobal(bufferHandler); |
| |
| if (structObject == null) |
| { |
| throw new InvalidOperationException("Failed to convert bytes to structure."); |
| } |
| |
| return structObject!; |
| } |
| |
| private byte[] NormalStrToHexByte(string str) |
| { |
| byte[] result = new byte[str.Length]; |
| |
| byte[] buffer = System.Text.Encoding.UTF8.GetBytes(str); |
| |
| for (int i = 0; i < buffer.Length; i++) |
| { |
| result[i] = Convert.ToByte(buffer[i].ToString("X2"), 16); |
| } |
| return result; |
| } |
| |
| private byte[] CreateMsgHead(ushort type, uint msgLen) |
| { |
| var msgHead = new SeerMessageHead |
| { |
| type = type, |
| length = msgLen |
| }; |
| return msgHead.ToBytes(); |
| } |
| |
| public static void PrintBytes(byte[] bytes) |
| { |
| foreach (byte b in bytes) |
| { |
| Console.Write("{0:X2} ", b); |
| } |
| |
| } |
| |
| |
| |
| |
| |
| } |
| |
| |
| |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
2023-02-15 flask_openv_video_streaming_来自miguelgrinberg大佬_写pythonsocketio的那个
2023-02-15 flask_socketio_rasip_video_stream_opencv
2022-02-15 autojs 读取多行文本 一行一行读取文本
2022-02-15 微信公众号 话题链接提取
2022-02-15 创建多层目录 文件写入
2022-02-15 微信公众号 爬虫 提取url
2022-02-15 cheerio 解析新浪博客目录列表