zoukankan      html  css  js  c++  java
  • 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);// 调用所有注册对象的方法
                }
            }
            #endregion
            private 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类
  • 相关阅读:
    安卓版php服务器的mysql数据库增删改查简单案例
    PHP之Mysql常用SQL语句示例的深入分析
    PHP文件上传主要代码讲解
    只能输入数字的文本框-php
    Unknown column '' in 'field list'解决方案
    PHP mysqli连接MySQL数据库
    Php连接及读取和写入mysql数据库的常用代码
    mysqli 操作数据库
    类的静态变量访问
    用JS添加文本框案例代码
  • 原文地址:https://www.cnblogs.com/tangxf/p/3692990.html
Copyright © 2011-2022 走看看