TCPIP通信

最近在开发TCPIP通信,封装了3个类,望各位大神指点指点。
  1 using System;
  2 using System.Collections.Generic;
  3 using System.Text;
  4 using System.Net.Sockets;
  5 using System.Threading;
  6 using System.Net;
  7 using System.Linq;
  8 using System.Net.NetworkInformation;
  9 
 10 namespace HY_RFID
 11 {
 12     public class MyTCPServer
 13     {
 14         public bool isExit = false;
 15         private TcpListener listener;
 16         public TcpClient readClient;
 17         List<ReadWriteObject> rws = new List<ReadWriteObject>();
 18         public List<TCPIP> ips = new List<TCPIP>();
 19 
 20         #region 创建事件
 21         //声明事件参数
 22         public class TcpClientArgs : EventArgs
 23         {
 24             public readonly TcpClient client;
 25             public TcpClientArgs(TcpClient client)
 26             {
 27                 this.client = client;
 28             }
 29         }
 30         public class BackMsgArgs : EventArgs
 31         {
 32             public readonly string backMsg;
 33             public BackMsgArgs(string backMsg)
 34             {
 35                 this.backMsg = backMsg;
 36             }
 37         }
 38         public class BackByteArgs : EventArgs
 39         {
 40             public readonly byte[] backByte;
 41             public BackByteArgs(byte[] backByte)
 42             {
 43                 this.backByte = backByte;
 44             }
 45         }
 46         public delegate void WaitConnectEventHandler(object sender,EventArgs e);
 47         public event WaitConnectEventHandler OnWaitConnect;
 48         protected virtual void WaitConnect()
 49         {
 50             if (OnWaitConnect != null)// 如果有对象注册
 51             {
 52                 OnWaitConnect(this, null);// 调用所有注册对象的方法
 53             }
 54         }
 55         //声明委托
 56         public delegate void SuccessConnectEventHandler(object sender, TcpClientArgs e);
 57         //声明事件
 58         public event SuccessConnectEventHandler OnSuccessConnect;
 59         //触发方法
 60         protected virtual void SuccessConnect(TcpClientArgs e)
 61         {
 62             if (OnSuccessConnect != null)// 如果有对象注册
 63             {
 64                 OnSuccessConnect(this, e);// 调用所有注册对象的方法
 65             }
 66         }
 67         public delegate void ReadCallBackMsgEventHandler(object sender, BackByteArgs e);
 68         public event ReadCallBackMsgEventHandler OnReadCallBack;
 69         protected virtual void ReadCallBackMsg(BackByteArgs e)
 70         {
 71             if (OnReadCallBack != null)// 如果有对象注册
 72             {
 73                 OnReadCallBack(this, e);// 调用所有注册对象的方法
 74             }
 75         }
 76         public delegate void ReadErrorCallBackMsgEventHandler(object sender, BackMsgArgs e);
 77         public event ReadErrorCallBackMsgEventHandler OnReadErrorCallBack;
 78         protected virtual void ReadErrorCallBackMsg(BackMsgArgs e)
 79         {
 80             if (OnReadErrorCallBack != null)// 如果有对象注册
 81             {
 82                 OnReadErrorCallBack(this, e);// 调用所有注册对象的方法
 83             }
 84         }
 85         #endregion
 86 
 87         //用于线程同步,初始状态设为非终止状态,使用手动重置方式
 88         private EventWaitHandle allDone = new EventWaitHandle(false, EventResetMode.ManualReset);
 89         //服务端监听方法
 90         public void ServerListen(int port)
 91         {
 92             //由于服务器要为多个客户服务,所以需要创建一个线程监听客户端连接请求
 93             isExit = false;
 94             if (!PortInUse(port))
 95             {
 96                 Thread myThread = new Thread(new ParameterizedThreadStart(AcceptConnect));
 97                 myThread.Start(port);
 98             }
 99             else
100             {
101                 throw new Exception("当前端口已被占用!");
102             }
103         }
104         /// <summary>
105         /// 检测但钱端口是否被占用
106         /// </summary>
107         /// <param name="port"></param>
108         /// <returns></returns>
109         private bool PortInUse(int port)
110         {
111             bool inUse = false;
112             //获取所有的监听连接
113             IPGlobalProperties ipProperties = IPGlobalProperties.GetIPGlobalProperties();
114             IPEndPoint[] ipEndPoints = ipProperties.GetActiveTcpListeners();
115             foreach (IPEndPoint endPoint in ipEndPoints)
116             {
117                 if (endPoint.Port == port)
118                 {
119                     inUse = true;
120                     break;
121                 }
122             }
123             return inUse;
124         }
125         //与客户机取得连接
126         private void AcceptConnect(object o)
127         {
128             try
129             {
130                 if (o == null) return;
131                 IPAddress ip4 = GetLocalIpv4() as IPAddress; 
132                 listener = new TcpListener(ip4, Convert.ToInt32(o));
133                 listener.Start();
134                 //引用在异步操作完成时调用的回调方法
135                 AsyncCallback callback = new AsyncCallback(AcceptTcpClientCallback);
136                 while (!isExit)
137                 {
138 
139                     //将事件的状态设为非终止
140                     allDone.Reset();
141                     //触发等待事件
142                     WaitConnect();
143                     //开始一个异步操作接受传入的连接尝试
144                     listener.BeginAcceptTcpClient(callback, listener);
145                     //阻塞当前线程,直到收到客户连接信号
146                     allDone.WaitOne();
147                     Thread.Sleep(100);
148                 }
149             }
150             catch (Exception ex)
151             {
152                 throw ex;
153             }
154         }
155         //获取本机IP
156         public object GetLocalIpv4()
157         {
158             //获取本机所有IP地址 
159             try
160             {
161                 IPAddress[] localips = Dns.GetHostAddresses(Dns.GetHostName());
162                 foreach (IPAddress ip in localips)
163                 {
164                     //找到本地所有IP地址符合IPV4协议的IP地址
165                     if (ip.AddressFamily == AddressFamily.InterNetwork)
166                     {
167                         return ip;
168                     }
169                 }
170             }
171             catch (Exception ex)
172             {
173                 throw ex;
174             }
175             return null;
176         }
177         // 连接客户端的回调函数
178         //ar是IAsyncResult类型的接口,表示异步操作的状态是由listener.BeginAcceptTcpClient(callback, listener)传递过来的
179         private void AcceptTcpClientCallback(IAsyncResult ar)
180         {
181             lock (this)
182             {
183                 try
184                 {
185                     if (isExit) return;
186                     //将事件状态设为终止状态,允许一个或多个等待线程继续
187                     allDone.Set();
188                     TcpListener myListener = (TcpListener)ar.AsyncState;
189                     //异步接收传入的连接,并创建新的TcpClient对象处理远程主机通信
190                     TcpClient client = myListener.EndAcceptTcpClient(ar);
191                     //已接受客户连接
192                     TcpClientArgs e = new TcpClientArgs(client);
193                     ReadWriteObject readWriteObject = new ReadWriteObject(client);
194                     rws.Add(readWriteObject);
195                     string[] strs=client.Client.RemoteEndPoint.ToString().Split(':');
196                     ips.RemoveAll(c => c.TargetIP == strs[0]);
197                     ips.Add(new TCPIP(strs[0], strs[1], DateTime.Now));
198                     //触发客户端连接成功事件
199                     SuccessConnect(e);
200                     readWriteObject.netStream.BeginRead(readWriteObject.readBytes, 0, readWriteObject.readBytes.Length, ReadCallback, readWriteObject);
201                 }
202                 catch (Exception ex)
203                 {
204                     throw ex;
205                 } 
206             }
207         }
208         private void ReadCallback(IAsyncResult ar)
209         {
210             try
211             {
212                 ReadWriteObject readWriteObject = (ReadWriteObject)ar.AsyncState;
213                 readClient=readWriteObject.client;
214                 if (readClient.Client.Poll(10, SelectMode.SelectRead) && (readClient.Client.Available == 0) | readClient.Client.Connected)
215                 {
216                     throw new Exception(readWriteObject.client.Client.RemoteEndPoint + "【断开】");
217                 }
218                 int length = readWriteObject.netStream.EndRead(ar);
219                 if (length == 0) return;
220                 List<byte> _byteData = new List<byte>();
221                 for (int i = 0; i < length; i++)
222                 {
223                     _byteData.Add(readWriteObject.readBytes[i]);
224                 }
225                 ReadCallBackMsg(new BackByteArgs(_byteData.ToArray()));
226                 if (isExit == false)
227                 {
228                     readWriteObject.InitReadArray();
229                     readWriteObject.netStream.BeginRead(readWriteObject.readBytes, 0, readWriteObject.readBytes.Length, ReadCallback, readWriteObject);
230                 }
231             }
232             catch (Exception ex)
233             {
234                 ReadErrorCallBackMsg(new BackMsgArgs(ex.Message));
235             }
236         }
237         public void SendString(string remoteEndPoint, string str)
238         {
239             try
240             {
241                 ReadWriteObject readWriteObject = rws.Where(c => c.client.Client.RemoteEndPoint.ToString() == remoteEndPoint).FirstOrDefault();
242                 if (readWriteObject.client.Client.Poll(10, SelectMode.SelectRead) && (readWriteObject.client.Client.Available == 0) || !readWriteObject.client.Client.Connected)
243                 {
244                     throw new Exception(remoteEndPoint + "【断开】");
245                 }
246                 if (readWriteObject != null)
247                 {
248                     readWriteObject.write = MyHelper.HexToByte(str);
249                     readWriteObject.netStream.BeginWrite(readWriteObject.write, 0, readWriteObject.write.Length, new AsyncCallback(SendCallBack), readWriteObject);
250                     readWriteObject.netStream.Flush();
251                     
252                 }
253             }
254             catch (Exception ex)
255             {
256                 throw ex;
257             }
258         }
259         private void SendCallBack(IAsyncResult ar)
260         {
261             ReadWriteObject readWriteObject = (ReadWriteObject)ar.AsyncState;
262             try
263             {
264                 readWriteObject.netStream.EndWrite(ar);
265             }
266             catch (Exception ex)
267             {
268                 throw ex;
269             }
270         }
271         /// <summary>
272         /// 停止服务
273         /// </summary>
274         public void StopServer()
275         {
276             isExit = true;
277             allDone.Set();
278             if (listener != null)
279                 listener.Stop();
280         }
281     }
282 }
TCPServer类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Net;
using System.Threading;namespace HY_RFID
{public class MyTcpClient{#region 创建事件public class RecMsgArgs : EventArgs{public readonly string recMsg;public RecMsgArgs(string recMsg){this.recMsg = recMsg;}}public class RecErrArgs : EventArgs{public readonly string recErr;public RecErrArgs(string recErr){this.recErr = recErr;}}public delegate void ReceivedMsgEventHandler(object sender, RecMsgArgs e);public event ReceivedMsgEventHandler OnReceived;protected virtual void ReceivedMsg(RecMsgArgs e){if (OnReceived != null)// 如果有对象注册
            {OnReceived(this, e);// 调用所有注册对象的方法
            }}public delegate void ReceivedErrorEventHandler(object sender, RecErrArgs e);public event ReceivedErrorEventHandler OnReceivedErr;protected virtual void ReceivedError(RecErrArgs e){if (OnReceivedErr != null)// 如果有对象注册
            {OnReceivedErr(this, e);// 调用所有注册对象的方法
            }}#endregionprivate bool isExit;private Socket socketClient = null;//连接服务端方法public void ClientConnect(string IP, string Port){isExit = false;//定义一个套字节监听  包含3个参数(IP4寻址协议,流式连接,TCP协议)socketClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//需要获取文本框中的IP地址IPAddress ipaddress = IPAddress.Parse(IP);//将获取的ip地址和端口号绑定到网络节点endpoint上IPEndPoint endpoint = new IPEndPoint(ipaddress, int.Parse(Port));//这里客户端套接字连接到网络节点(服务端)用的方法是Connect 而不是Bind
            socketClient.Connect(endpoint);//创建一个线程 用于监听服务端发来的消息Thread threadClient = new Thread(RecMsg);//将窗体线程设置为与后台同步threadClient.IsBackground = true;//启动线程
            threadClient.Start();}// 发送节目全屏byte串信息到服务端的方法public void ClientSendMsg(string msg){try{if (socketClient.Poll(10, SelectMode.SelectRead) && (socketClient.Available == 0) || !socketClient.Connected){throw new Exception(socketClient.RemoteEndPoint + "已断开!");}Byte[] data = System.Text.Encoding.Default.GetBytes(msg);socketClient.Send(data, data.Length, SocketFlags.None);//发送信息
            }catch(Exception ex){throw ex;}}//接收服务端发来信息的方法public void RecMsg(){while (!isExit) //持续监听服务端发来的消息
            {try{bool o = socketClient.Poll(10, SelectMode.SelectRead);if (o) break;//定义一个1024*200的内存缓冲区 用于临时性存储接收到的信息byte[] arrRecMsg = new byte[1024 * 200];//将客户端套接字接收到的数据存入内存缓冲区, 并获取其长度int length = socketClient.Receive(arrRecMsg);if (length == 0) return;string recMsg = Encoding.Default.GetString(arrRecMsg, 0, length);ReceivedMsg(new RecMsgArgs(recMsg));}catch (SocketException ex){ReceivedError(new RecErrArgs(ex.Message));}}}/// <summary>/// 断开链接/// </summary>public void StopConnect(){if (socketClient != null){socketClient.Close();isExit = true;}}}
}
TCPClient类
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Text;
 4 using System.Net.Sockets;
 5 
 6 namespace HY_RFID
 7 {
 8     public class ReadWriteObject
 9     {
10         public TcpClient client;
11         public NetworkStream netStream;
12         public byte[] readBytes;
13         public byte[] write;
14         public ReadWriteObject(TcpClient client)
15         {
16             this.client = client;
17             netStream = client.GetStream();
18             readBytes = new byte[client.ReceiveBufferSize];
19             write=new byte[client.SendBufferSize];
20         }
21         public void InitReadArray()
22         {
23             readBytes = new byte[client.ReceiveBufferSize];
24         }
25         public void InitWriteArray()
26         { 
27             write=new byte[client.SendBufferSize];
28         }
29     }
30 }
ReadWriteObject类

 

转载于:https://www.cnblogs.com/tangxf/p/3692990.html

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

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

相关文章

Python 20 秒画完小猪佩奇“社会人”!

每天写代码的程序员&#xff0c;你们知道今年社交平台上最火的带货女王是谁吗&#xff1f;范冰冰&#xff1f;杨幂&#xff1f;Angelababy&#xff1f;不&#xff0c;是猪猪女孩小猪佩奇。 如果你经常用抖音、快手、B 站、知乎、微博……或者类似的任何一个内容或社交平台&…

使用RNN预测文档归属作者

文章目录1. 文本处理2. 文本序列化3. 数据集拆分4. 建立RNN模型5. 训练6. 测试参考 基于深度学习的自然语言处理 1. 文本处理 数据预览 # 有两个作者的文章&#xff08;A, B&#xff09;&#xff0c;定义为0&#xff0c; 1 A 0 # hamilton B 1 # madison UNKNOWN -1# 把…

LeetCode 1674. 使数组互补的最少操作次数(差分思想)

文章目录1. 题目2. 解题1. 题目 给你一个长度为 偶数 n 的整数数组 nums 和一个整数 limit 。 每一次操作&#xff0c;你可以将 nums 中的任何整数替换为 1 到 limit 之间的另一个整数。 如果对于所有下标 i&#xff08;下标从 0 开始&#xff09;&#xff0c;nums[i] nums[…

Kaggle 房价预测竞赛优胜方案:用 Python 进行全面数据探索

&#xff3b;导读&#xff3d;Kaggle 的房价预测竞赛从 2016 年 8 月开始&#xff0c;到 2017 年 2 月结束。这段时间内&#xff0c;超过 2000 多人参与比赛&#xff0c;选手采用高级回归技术&#xff0c;基于我们给出的 79 个特征&#xff0c;对房屋的售价进行了准确的预测。今…

使用GRU单元的RNN模型生成唐诗

文章目录1. 读取数据2. 字符索引3. 创建文本序列4. 创建文本编码序列5. 使用GRU单元建立RNN模型6. 文本生成参考 基于深度学习的自然语言处理 本文使用 GRU 单元建立 RNN 网络&#xff0c;使用唐诗三百首进行训练&#xff0c;使用模型生成唐诗。 GRU RNN 网络能够克服简单RNN…

Python数据结构常见的八大排序算法(详细整理)

前言 八大排序&#xff0c;三大查找是《数据结构》当中非常基础的知识点&#xff0c;在这里为了复习顺带总结了一下常见的八种排序算法。 常见的八大排序算法&#xff0c;他们之间关系如下&#xff1a; 排序算法.png 他们的性能比较&#xff1a; 下面&#xff0c;利用Python分别…

牛客 牛牛选物(01背包)

文章目录1. 题目2. 解题1. 题目 链接&#xff1a;https://ac.nowcoder.com/acm/contest/9887/A 来源&#xff1a;牛客网 牛牛有现在有n个物品&#xff0c;每个物品有一个体积v[i]和重量g[i],他想选择其中总体积恰好为V的若干个物品&#xff0c;想使这若干个物品的总重量最大&…

微信小程序最常用的布局——Flex布局

最近在学习微信小程序&#xff0c;在设计首页布局的时候&#xff0c;新认识了一种布局方式display:flex 1 .container { 2 display: flex; 3 flex-direction: column; 4 align-items: center; 5 background-color: #b3d4db; 6 } 编译之后的效果很明显&#xff0c;界面…

LeetCode 649. Dota2 参议院(循环队列)

文章目录1. 题目2. 解题1. 题目 Dota2 的世界里有两个阵营&#xff1a;Radiant(天辉)和 Dire(夜魇) Dota2 参议院由来自两派的参议员组成。现在参议院希望对一个 Dota2 游戏里的改变作出决定。他们以一个基于轮为过程的投票进行。在每一轮中&#xff0c;每一位参议员都可以行…

'[linux下tomcat 配置

tomcat目录结构bin ——Tomcat执行脚本目录 conf ——Tomcat配置文件 lib ——Tomcat运行需要的库文件&#xff08;JARS&#xff09; logs ——Tomcat执行时的LOG文件 temp ——Tomcat临时文件存放目录 webapps ——Tomcat的主要Web发布目录&#xff08;存放我们自己的JSP,SER…

微信小程序基础(一)

一.注册小程序账号&#xff0c;下载IDE 1.官网注册https://mp.weixin.qq.com/&#xff0c;并下载IDE。 2.官方文档一向都是最好的学习资料。 注意&#xff1a; &#xff08;1&#xff09;注册账号之后会有一个appid&#xff0c;新建项目的时候需要填上&#xff0c;不然很多…

[Kaggle] Spam/Ham Email Classification 垃圾邮件分类(RNN/GRU/LSTM)

文章目录1. 读入数据2. 文本处理3. 建模4. 训练5. 测试练习地址&#xff1a;https://www.kaggle.com/c/ds100fa19 相关博文 [Kaggle] Spam/Ham Email Classification 垃圾邮件分类&#xff08;spacy&#xff09; [Kaggle] Spam/Ham Email Classification 垃圾邮件分类&#xff…

微信小程序中实现瀑布流布局和无限加载

瀑布流布局是一种比较流行的页面布局方式&#xff0c;最典型的就是Pinterest.com&#xff0c;每个卡片的高度不都一样&#xff0c;形成一种参差不齐的美感。 在HTML5中&#xff0c;我们可以找到很多基于jQuery之类实现的瀑布流布局插件&#xff0c;轻松做出这样的布局形式。在…

LeetCode 1684. 统计一致字符串的数目(哈希)

文章目录1. 题目2. 解题1. 题目 给你一个由不同字符组成的字符串 allowed 和一个字符串数组 words 。 如果一个字符串的每一个字符都在 allowed 中&#xff0c;就称这个字符串是 一致 字符串。 请你返回 words 数组中 一致 字符串的数目。 示例 1&#xff1a; 输入&#xff…

微信小程序:页面跳转时传递数据到另一个页面

一、功能描述 页面跳转时&#xff0c;同时把当前页面的数据传递给跳转的目标页面&#xff0c;并在跳转后的目标页面进行展示 二、功能实现 1. 代码实现 test1页面 // pages/test1/test1.js Page({/*** 页面的初始数据*/data: {name:Tom,age:12},buttonListener:function(){…

LeetCode 1685. 有序数组中差绝对值之和(前缀和)

文章目录1. 题目2. 解题1. 题目 给你一个 非递减 有序整数数组 nums 。 请你建立并返回一个整数数组 result&#xff0c;它跟 nums 长度相同&#xff0c;且result[i] 等于 nums[i] 与数组中所有其他元素差的绝对值之和。 换句话说&#xff0c; result[i] 等于 sum(|nums[i]-…

对一个 复杂的json结果进行取值的例子

1 JSON结果集 1 [2 {3 "J_LP_OPERATE_MAIN": {4 "ID": "1900036295",5 "FILL_MAN": "周兴福",6 "FILL_DEPT": "运维一班",7 "STATE…

微信小程序正则判断姓名和手机号

一、页面效果 二、json文件 //获取应用实例 const app getApp() Page({/*** 页面的初始数据*/data: {array: [速美, 现代, 淮安],mode: scaleToFill,src: ../../images/1.png,userInfo: {},hasUserInfo: false,canIUse: wx.canIUse(button.open-type.getUserInfo),userName: …

LeetCode 1686. 石子游戏 VI(贪心)

文章目录1. 题目2. 解题283 / 1660&#xff0c;前17%681 / 6572&#xff0c;前10.4%1. 题目 Alice 和 Bob 轮流玩一个游戏&#xff0c;Alice 先手。 一堆石子里总共有 n 个石子&#xff0c;轮到某个玩家时&#xff0c;他可以 移出 一个石子并得到这个石子的价值。 Alice 和 B…

T4生成实体和简单的CRUD操作

主要跟大家交流下T4,我这里针对的是mysql,我本人比较喜欢用mysql,所以语法针对mysql,所以你要准备mysql的DLL了,同理sqlserver差不多,有兴趣可以自己写写,首先网上找了一个T4的帮助类,得到一些数据库属性,命名为 DbHelper.ttinclude <# template debug"false" hos…