现在的位置: 首页 > 综合 > 正文

[C#]事件驱动的SOCKET类

2018年10月20日 ⁄ 综合 ⁄ 共 11421字 ⁄ 字号 评论关闭
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Text;  
  4. using System.Net.Sockets;  
  5. using System.Threading;  
  6. using log4net;  
  7.   
  8. namespace CallOut  
  9. {  
  10.     class CallCenterCom  
  11.     {  
  12.         const int DataPackLen = 102440;  
  13.         const int DataHeadLen = 5;  
  14.         const int APIVersion = 1;  
  15.   
  16.         //缓存数据大小  
  17.         private const int DataBufferSize = 1024 * 50;         
  18.   
  19.         private delegate void ComResEvent(string ResCode, Socket socket);  
  20.   
  21.         public class RecEventArgs : System.EventArgs  
  22.         {  
  23.             public string vDataPack;  
  24.         }  
  25.   
  26.         public class SocketEventArgs : System.EventArgs  
  27.         {  
  28.             //00000 断开连接  
  29.             //10000 连接成功  
  30.             //10001 正在连接  
  31.             public string ResCode;  //SOCKET状态码     
  32.             public string ErrorStr; //错误内容  
  33.         }  
  34.   
  35.         /// <summary>  
  36.         /// 客户端SOCKET类  
  37.         /// </summary>  
  38.         public class TcsClientCom  
  39.         {  
  40.             Socket socket;  
  41.             string host;  
  42.             int port;  
  43.             ILog log = null;  //客户端数据包日志记录组件              
  44.   
  45.             private int DataBufferSizeLast = 0;                     //最后一留下来的数据总长度  
  46.             private byte[] DataBuffer = new byte[DataBufferSize];  // Receive buffer.    
  47.             private byte[] DataBufferLast;          
  48.   
  49.             public string EndPoint  
  50.             {  
  51.                 get { return host + ":" + port.ToString(); }  
  52.             }  
  53.   
  54.             public string RemoteEndPoint  
  55.             {  
  56.                 get { return socket.RemoteEndPoint.ToString(); }  
  57.             }  
  58.   
  59.             //接收事件参数  
  60.             RecEventArgs Rec_e = new RecEventArgs();  
  61.             //SOCKET事件参数  
  62.             SocketEventArgs Socket_e = new SocketEventArgs();  
  63.   
  64.             //接收事件  
  65.             public delegate void OperResEvent(object sender, RecEventArgs e);  
  66.             public event OperResEvent RecEvent;  
  67.   
  68.             //SOCKET状态事件  
  69.             public delegate void ComResEvent(object sender, SocketEventArgs e);  
  70.             public event ComResEvent SocketEvent;  
  71.   
  72.   
  73.             public TcsClientCom(string host, int port)  
  74.             {  
  75.                 this.host = host;  
  76.                 this.port = port;  
  77.                 log = log4net.LogManager.GetLogger("DataPack");  //实例化客户段数据包日志组件  
  78.             }  
  79.   
  80.             public void Connect()  
  81.             {  
  82.                 Thread con = new Thread(this.Connect_Thread);  
  83.                 con.IsBackground = true;  
  84.                 con.Start();                  
  85.             }  
  86.   
  87.             //连接线程  
  88.             public void Connect_Thread()  
  89.             {  
  90.                 try  
  91.                 {  
  92.                     //socket.SetSocketOption(SocketOptionLevel.Tcp,                          
  93.                     socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);  
  94.                     socket.ReceiveTimeout = 2000;                      
  95.                     //正在连接  
  96.                     Socket_e.ResCode = "10001";  
  97.                     SocketEvent(this, Socket_e);  
  98.                     socket.Connect(host, port);  
  99.                     SocketRead();  
  100.                     //连接成功  
  101.                     Socket_e.ResCode = "10000";  
  102.                     SocketEvent(this, Socket_e);  
  103.                 }  
  104.                 catch (Exception Ex)  
  105.                 {  
  106.                     Socket_e.ResCode = "00000";  
  107.                     Socket_e.ErrorStr = Ex.Message;  
  108.                     SocketEvent(this, Socket_e);  
  109.                 }  
  110.             }  
  111.   
  112.             public void DisConnect()  
  113.             {  
  114.                 socket.Disconnect(false);  
  115.             }  
  116.   
  117.             public void ReConnect()  
  118.             {  
  119.                 socket.Disconnect(true);  
  120.                 this.Connect();  
  121.             }  
  122.   
  123.             public void SocketRead()  
  124.             {  
  125.                 Thread tRead = new Thread(Thread_Read);  
  126.                 tRead.IsBackground = true;  
  127.                 tRead.Start();  
  128.             }  
  129.   
  130.             //接收线程  
  131.             public void Thread_Read()  
  132.             {  
  133.                 while (true)  
  134.                 {  
  135.                     try  
  136.                     {  
  137.                         if (socket.Poll(-1, SelectMode.SelectRead))  
  138.                         {  
  139.                             //使用数据缓冲  
  140.                             byte[] DataBuffer = new byte[DataBufferSize - DataBufferSizeLast];  
  141.                             int receivedBytesCount = socket.Receive(DataBuffer, DataBufferSize - DataBufferSizeLast, SocketFlags.None);  
  142.   
  143.                             if (receivedBytesCount == 0)  
  144.                             {  
  145.                                 //socket连接已断开  
  146.                                 Socket_e.ResCode = "00000";  
  147.                                 SocketEvent(this, Socket_e);                   
  148.                                 return;  
  149.                             }  
  150.   
  151.                             int iTempDataBufferSizeLast = 0;  
  152.                             byte[] TempBytes = new byte[receivedBytesCount + DataBufferSizeLast];   //receivedBytesCount + DataBufferSizeLast  
  153.   
  154.                             if (DataBufferLast != null)  
  155.                             {  
  156.                                 Buffer.BlockCopy(DataBufferLast, 0, TempBytes, 0, DataBufferSizeLast);  
  157.                                 iTempDataBufferSizeLast = DataBufferSizeLast;  
  158.                                 DataBufferLast = null;   //---- 使用完后 为空值  
  159.                                 DataBufferSizeLast = 0;  
  160.                             }  
  161.                             Buffer.BlockCopy(DataBuffer, 0, TempBytes, iTempDataBufferSizeLast, receivedBytesCount);  
  162.                             EncodingBytes(TempBytes, receivedBytesCount + iTempDataBufferSizeLast);  
  163.                              
  164.                         }  
  165.                         else if (socket.Poll(-1, SelectMode.SelectError))  
  166.                         {  
  167.                             //TODO : SOCKET错误  
  168.                         }  
  169.                     }  
  170.                     catch (SocketException e)  
  171.                     {  
  172.                         //10035 == WSAEWOULDBLOCK  
  173.                         if (e.NativeErrorCode.Equals(10035))  
  174.                         {  
  175.                             //仍然处于连接状态,但是发送可能被阻塞  
  176.                         }  
  177.                         else  
  178.                         {  
  179.                             //连接错误,返回错误代码:e.NativeErrorCode  
  180.                             Socket_e.ResCode = e.NativeErrorCode.ToString();  
  181.                             SocketEvent(this, Socket_e);  
  182.                             return;  
  183.                         }  
  184.                     }  
  185.                 }  
  186.             }  
  187.   
  188.             private void EncodingBytes(byte[] Totalbytes, int TotalBytesCount)  
  189.             {                 
  190.                 try  
  191.                 {  
  192.                     //如果包的长度不到5位则,将本次读取的数据合并到DataBufferLast字节数组中  
  193.                     if (Totalbytes.Length <= 5)  
  194.                     {  
  195.                         DataBufferLast = new byte[TotalBytesCount];  
  196.                         Buffer.BlockCopy(Totalbytes, 0, DataBufferLast, 0, TotalBytesCount);  
  197.                         return;  
  198.                     }  
  199.   
  200.                     //记录包长度的字节  
  201.                     byte[] TempHeadBytes = new byte[4];  
  202.                     //包的第2到5位记录包的长度    
  203.                     Buffer.BlockCopy(Totalbytes, 1, TempHeadBytes, 0, 4);  
  204.                     //将字节转换为整型的长度  
  205.                     int TempPackLen = BitConverter.ToInt32(TempHeadBytes, 0);     //每个包的长度   
  206.   
  207.                     //如果包的长度加包头的长度大于接收的总字节数  
  208.                     if ((TempPackLen + DataHeadLen) > TotalBytesCount)  
  209.                     {  
  210.                         DataBufferSizeLast = TotalBytesCount;  
  211.                         DataBufferLast = new byte[TotalBytesCount];  
  212.                         Buffer.BlockCopy(Totalbytes, 0, DataBufferLast, 0, TotalBytesCount);  
  213.                         return;  
  214.                     }  
  215.   
  216.                     byte[] TempPackBytes = new byte[TempPackLen];  
  217.                     for (int i = 0; i < TempPackLen; i++)  
  218.                     {  
  219.                         TempPackBytes[i] = Totalbytes[i + DataHeadLen];  
  220.                     }  
  221.   
  222.                     string receivedStr = System.Text.Encoding.Default.GetString(TempPackBytes);  
  223.   
  224.                     Rec_e.vDataPack = receivedStr;  
  225.                     log.Info(receivedStr);  //记录数据包日志                              
  226.                     RecEvent(this, Rec_e);  //通知外部事件                    
  227.   
  228.                     if (TotalBytesCount > DataHeadLen + TempPackLen)  
  229.                     {  
  230.                         byte[] Bytes = new byte[TotalBytesCount - DataHeadLen - TempPackLen];  
  231.                         Buffer.BlockCopy(Totalbytes, DataHeadLen + TempPackLen, Bytes, 0, TotalBytesCount - DataHeadLen - TempPackLen);  
  232.                         this.EncodingBytes(Bytes, TotalBytesCount - DataHeadLen - TempPackLen);  
  233.                     }  
  234.                 }  
  235.   
  236.                 catch (SocketException ex)  
  237.                 {  
  238.                     log.Info("EncodingBytes:" + ex.Message + "ErrorCode:" + ex.ErrorCode.ToString());  
  239.                 }  
  240.                 catch (Exception ex)  
  241.                 {  
  242.                     log.Info("EncodingBytes:" + ex.Message);  
  243.                 }  
  244.             }  
  245.   
  246.             //判断socket是否连接状态  
  247.             public bool IsConnected()  
  248.             {  
  249.                 if (socket.Poll(-1, SelectMode.SelectRead))  
  250.                 {  
  251.                     byte[] tmp = new byte[1];  
  252.                     int nRead = socket.Receive(tmp);  
  253.                     if (nRead == 0)  
  254.                     {  
  255.                         //socket连接已断开  
  256.                         return false;  
  257.                     }  
  258.                 }  
  259.                 return true;  
  260.                  
  261.             }  
  262.   
  263.             public bool Send(string vDataPack)  
  264.             {  
  265.   
  266.                 byte[] Ver = Encoding.Default.GetBytes(APIVersion.ToString());  
  267.   
  268.                 byte[] Len = new byte[4];  
  269.                 Len = Encoding.Default.GetBytes(vDataPack.Length.ToString());  
  270.   
  271.                 byte[] msg = Encoding.Default.GetBytes(vDataPack);  
  272.   
  273.                 byte[] PackageBytes = new byte[msg.Length + DataHeadLen];  
  274.   
  275.                 byte[] b4 = Int32ToBytes((UInt32)(msg.Length));  
  276.   
  277.                 Ver.CopyTo(PackageBytes, 0);  
  278.                 b4.CopyTo(PackageBytes, 1);  
  279.   
  280.                 msg.CopyTo(PackageBytes, DataHeadLen);  
  281.                   
  282.                 //记录发送包日志  
  283.                 log.Info(Encoding.Default.GetString(PackageBytes, 5, PackageBytes.Length - 5));                  
  284.                 try  
  285.                 {  
  286.                     int i = socket.Send(PackageBytes);  
  287.                     return true;  
  288.                 }  
  289.                 catch //SocketException e  
  290.                 {  
  291.                     return false;  
  292.                 }  
  293.             }  
  294.   
  295.             // 4字节整型 --> 字节数组(Java队列用的序,低位在前,高位在后)  
  296.             public byte[] Int32ToBytes(UInt32 i)  
  297.             {  
  298.                 byte[] bytes = new byte[4];  
  299.                 bytes[0] = (byte)(i % 256);    //每8位为一个字节  
  300.                 bytes[1] = (byte)(i / 256);  
  301.                 bytes[2] = (byte)(i / (65536));  
  302.                 bytes[3] = (byte)(i / (16777216));  
  303.                 return bytes;  
  304.             }  
  305.         }  
  306.   
  307.         /// <summary>  
  308.         /// 服务端SOCKET类  
  309.         /// </summary>  
  310.         public class TcsServerCom  
  311.         {  
  312.   
  313.         }  
  314.   
  315.     }  

抱歉!评论已关闭.