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     }
  • 相关阅读:
    [MacOS]Sublime text3 安装(一)
    [RHEL8]开启BBR
    PAT Advanced 1136 A Delayed Palindrome (20分)
    PAT Advanced 1144 The Missing Number (20分)
    PAT Advanced 1041 Be Unique (20分)
    PAT Advanced 1025 PAT Ranking (25分)
    PAT Advanced 1022 Digital Library (30分)
    PAT Advanced 1019 General Palindromic Number (20分)
    PAT Advanced 1011 World Cup Betting (20分)
    PAT Advanced 1102 Invert a Binary Tree (25分)
  • 原文地址:https://www.cnblogs.com/jonney-wang/p/5723799.html
Copyright © 2011-2022 走看看