zoukankan      html  css  js  c++  java
  • SocketTcpServer

    自定义SocketTcpServer,虽然现在有很多这样的组件,但是有时候还是需要把它集成在你的框架或者产品中,不需要特别强大的功能,根据需求定制。最基本的一个问题是判断数据包的结束,没有像supersocket那样默认以换行作为一个命令的结束,如果需要可以改善。

      1     public interface ISocketTcpServer
      2     {
      3         void Listen();
      4         void Stop();
      5         void SendData(byte[] data, Socket client);
      6 
      7         event ReceiveDataHandler ReceivedDataEvent;
      8         event OnlineChangeHandler OnlineChangeEvent;
      9         event ErrorHandler ErrorEvent;
     10     }
     11 
     12     public delegate void ReceiveDataHandler(SocketState state);
     13 
     14     public delegate void OnlineChangeHandler(int onlines, EndPoint client);
     15 
     16     public delegate void ErrorHandler(string error, EndPoint client);
     17 
     18     public class SocketTcpServer : ISocketTcpServer
     19     {
     20         private readonly Socket _tcpSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
     21         public readonly EndPoint LocalPoint;
     22         public readonly List<SocketState> ClientList = new List<SocketState>();
     23         public bool IsListening;
     24 
     25         public SocketTcpServer(IPEndPoint localPoint)
     26         {
     27             LocalPoint = localPoint;
     28         }
     29 
     30         public void Listen()
     31         {
     32             _tcpSocket.Bind(LocalPoint);
     33             _tcpSocket.Listen(1000);
     34             _tcpSocket.BeginAccept(AcceptClientCallBack, _tcpSocket);
     35             IsListening = true;
     36         }
     37 
     38         public void Stop()
     39         {
     40             IsListening = false;
     41             foreach (var state in ClientList)
     42             {
     43                 state.ClientSocket.Close();
     44             }
     45             ClientList.Clear();
     46             _tcpSocket.Close();
     47             OnlineChangeEvent?.Invoke(ClientList.Count, new IPEndPoint(IPAddress.Any, 0));
     48         }
     49 
     50         private void AcceptClientCallBack(IAsyncResult ar)
     51         {
     52             var server = ar.AsyncState as Socket;
     53             if (IsListening && server != null)
     54             {
     55                 try
     56                 {
     57                     var client = server.EndAccept(ar);
     58                     var clientState = new SocketState()
     59                     {
     60                         ClientSocket = client,
     61                         RemotePoint = client.RemoteEndPoint,
     62                     };
     63                     var tem = ClientList.FirstOrDefault(x => x.RemotePoint.Equals(clientState.RemotePoint));
     64                     if (tem != null)
     65                     {
     66                         tem.ClientSocket.Close();
     67                         ClientList.Remove(tem);
     68                     }
     69                     ClientList.Add(clientState);
     70                     BeginReveive(client);
     71                     OnlineChangeEvent?.Invoke(ClientList.Count, client.RemoteEndPoint);
     72                 }
     73                 catch (Exception error)
     74                 {
     75                     ErrorEvent?.Invoke(error.Message, null);
     76                 }
     77                 finally
     78                 {
     79                     server.BeginAccept(AcceptClientCallBack, server);
     80                 }
     81             }
     82         }
     83 
     84         private void BeginReveive(Socket client)
     85         {
     86             if (client.Connected)
     87             {
     88                 var state = new SocketState()
     89                 {
     90                     ClientSocket = client,
     91                     RemotePoint = client.RemoteEndPoint,
     92                 };
     93                 client.BeginReceiveFrom(
     94                     state.Buffer,
     95                     0,
     96                     state.Buffer.Length,
     97                     SocketFlags.None,
     98                     ref state.RemotePoint,
     99                     ReceiveCallback,
    100                     state);
    101             }
    102         }
    103 
    104         private void ReceiveCallback(IAsyncResult ar)
    105         {
    106             var state = ar.AsyncState as SocketState;
    107             try
    108             {
    109                 if (state != null && state.ClientSocket.Connected)
    110                 {
    111                     state.DataLen = state.ClientSocket.EndReceiveFrom(ar, ref state.RemotePoint);
    112                     if (state.DataLen == 0)
    113                     {
    114                         state.ClientSocket.Close();
    115                         var tem = ClientList.FirstOrDefault(x => x.RemotePoint.Equals(state.RemotePoint));
    116                         ClientList.Remove(tem);
    117                         OnlineChangeEvent?.Invoke(ClientList.Count, state.RemotePoint);
    118                     }
    119                     else
    120                     {
    121                         byte[] receivedData = new byte[state.DataLen];
    122                         Array.Copy(state.Buffer, 0, receivedData, 0, state.DataLen);
    123                         state.Buffer = receivedData;
    124                         ReceivedDataEvent?.Invoke(state);
    125                     }
    126                 }
    127             }
    128             catch (Exception error)
    129             {
    130                 ErrorEvent?.Invoke(error.Message, state.RemotePoint);
    131                 state.ClientSocket.Close();
    132                 var tem = ClientList.FirstOrDefault(x => x.RemotePoint.Equals(state.RemotePoint));
    133                 ClientList.Remove(tem);
    134                 OnlineChangeEvent?.Invoke(ClientList.Count, state.RemotePoint);
    135             }
    136             finally
    137             {
    138                 if (state != null) BeginReveive(state.ClientSocket);
    139             }
    140         }
    141 
    142         public void SendData(byte[] data, Socket client)
    143         {
    144             if (client.Connected)
    145             {
    146                 var state = new SocketState()
    147                 {
    148                     ClientSocket = client,
    149                     RemotePoint = client.RemoteEndPoint,
    150                     Buffer = data,
    151                     DataLen = data.Length,
    152                 };
    153                 client.BeginSendTo(data, 0, data.Length, SocketFlags.None, state.RemotePoint, SendCallback, state);
    154             }
    155         }
    156 
    157         private void SendCallback(IAsyncResult ar)
    158         {
    159             var state = ar.AsyncState as SocketState;
    160             try
    161             {
    162                 if (state != null && state.ClientSocket.Connected)
    163                 {
    164                     state.ClientSocket.EndSendTo(ar);
    165                 }
    166             }
    167             catch (Exception error)
    168             {
    169                 ErrorEvent?.Invoke(error.Message, state.RemotePoint);
    170             }
    171         }
    172 
    173         public event ReceiveDataHandler ReceivedDataEvent;
    174 
    175         public event OnlineChangeHandler OnlineChangeEvent;
    176 
    177         public event ErrorHandler ErrorEvent;
    178     }
    179 
    180     public class SocketState
    181     {
    182         public byte[] Buffer = new byte[1024*24];
    183         public Socket ClientSocket;
    184         public int DataLen;
    185         public EndPoint RemotePoint;
    186     }
  • 相关阅读:
    爬虫相关知识(二 )xpath
    爬虫相关知识(一)
    html基础知识
    接口和异常
    继承与多态
    方法与方法重载,方法重写
    面向对象预习随笔
    《深入浅出MFC》第三章 MFC六大关键技术之仿真
    《深入浅出MFC》第二章 C++的重要性质
    《深入浅出MFC》第一章 Win32基本程序概念
  • 原文地址:https://www.cnblogs.com/jonney-wang/p/5723799.html
Copyright © 2011-2022 走看看