- using System;
- using System.Collections.Generic;
- using System.Text;
- using System.Net.Sockets;
- using System.Threading;
- using log4net;
- namespace CallOut
- {
- class CallCenterCom
- {
- const int DataPackLen = 102440;
- const int DataHeadLen = 5;
- const int APIVersion = 1;
- //缓存数据大小
- private const int DataBufferSize = 1024 * 50;
- private delegate void ComResEvent(string ResCode, Socket socket);
- public class RecEventArgs : System.EventArgs
- {
- public string vDataPack;
- }
- public class SocketEventArgs : System.EventArgs
- {
- //00000 断开连接
- //10000 连接成功
- //10001 正在连接
- public string ResCode; //SOCKET状态码
- public string ErrorStr; //错误内容
- }
- /// <summary>
- /// 客户端SOCKET类
- /// </summary>
- public class TcsClientCom
- {
- Socket socket;
- string host;
- int port;
- ILog log = null; //客户端数据包日志记录组件
- private int DataBufferSizeLast = 0; //最后一留下来的数据总长度
- private byte[] DataBuffer = new byte[DataBufferSize]; // Receive buffer.
- private byte[] DataBufferLast;
- public string EndPoint
- {
- get { return host + ":" + port.ToString(); }
- }
- public string RemoteEndPoint
- {
- get { return socket.RemoteEndPoint.ToString(); }
- }
- //接收事件参数
- RecEventArgs Rec_e = new RecEventArgs();
- //SOCKET事件参数
- SocketEventArgs Socket_e = new SocketEventArgs();
- //接收事件
- public delegate void OperResEvent(object sender, RecEventArgs e);
- public event OperResEvent RecEvent;
- //SOCKET状态事件
- public delegate void ComResEvent(object sender, SocketEventArgs e);
- public event ComResEvent SocketEvent;
- public TcsClientCom(string host, int port)
- {
- this.host = host;
- this.port = port;
- log = log4net.LogManager.GetLogger("DataPack"); //实例化客户段数据包日志组件
- }
- public void Connect()
- {
- Thread con = new Thread(this.Connect_Thread);
- con.IsBackground = true;
- con.Start();
- }
- //连接线程
- public void Connect_Thread()
- {
- try
- {
- //socket.SetSocketOption(SocketOptionLevel.Tcp,
- socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
- socket.ReceiveTimeout = 2000;
- //正在连接
- Socket_e.ResCode = "10001";
- SocketEvent(this, Socket_e);
- socket.Connect(host, port);
- SocketRead();
- //连接成功
- Socket_e.ResCode = "10000";
- SocketEvent(this, Socket_e);
- }
- catch (Exception Ex)
- {
- Socket_e.ResCode = "00000";
- Socket_e.ErrorStr = Ex.Message;
- SocketEvent(this, Socket_e);
- }
- }
- public void DisConnect()
- {
- socket.Disconnect(false);
- }
- public void ReConnect()
- {
- socket.Disconnect(true);
- this.Connect();
- }
- public void SocketRead()
- {
- Thread tRead = new Thread(Thread_Read);
- tRead.IsBackground = true;
- tRead.Start();
- }
- //接收线程
- public void Thread_Read()
- {
- while (true)
- {
- try
- {
- if (socket.Poll(-1, SelectMode.SelectRead))
- {
- //使用数据缓冲
- byte[] DataBuffer = new byte[DataBufferSize - DataBufferSizeLast];
- int receivedBytesCount = socket.Receive(DataBuffer, DataBufferSize - DataBufferSizeLast, SocketFlags.None);
- if (receivedBytesCount == 0)
- {
- //socket连接已断开
- Socket_e.ResCode = "00000";
- SocketEvent(this, Socket_e);
- return;
- }
- int iTempDataBufferSizeLast = 0;
- byte[] TempBytes = new byte[receivedBytesCount + DataBufferSizeLast]; //receivedBytesCount + DataBufferSizeLast
- if (DataBufferLast != null)
- {
- Buffer.BlockCopy(DataBufferLast, 0, TempBytes, 0, DataBufferSizeLast);
- iTempDataBufferSizeLast = DataBufferSizeLast;
- DataBufferLast = null; //---- 使用完后 为空值
- DataBufferSizeLast = 0;
- }
- Buffer.BlockCopy(DataBuffer, 0, TempBytes, iTempDataBufferSizeLast, receivedBytesCount);
- EncodingBytes(TempBytes, receivedBytesCount + iTempDataBufferSizeLast);
- }
- else if (socket.Poll(-1, SelectMode.SelectError))
- {
- //TODO : SOCKET错误
- }
- }
- catch (SocketException e)
- {
- //10035 == WSAEWOULDBLOCK
- if (e.NativeErrorCode.Equals(10035))
- {
- //仍然处于连接状态,但是发送可能被阻塞
- }
- else
- {
- //连接错误,返回错误代码:e.NativeErrorCode
- Socket_e.ResCode = e.NativeErrorCode.ToString();
- SocketEvent(this, Socket_e);
- return;
- }
- }
- }
- }
- private void EncodingBytes(byte[] Totalbytes, int TotalBytesCount)
- {
- try
- {
- //如果包的长度不到5位则,将本次读取的数据合并到DataBufferLast字节数组中
- if (Totalbytes.Length <= 5)
- {
- DataBufferLast = new byte[TotalBytesCount];
- Buffer.BlockCopy(Totalbytes, 0, DataBufferLast, 0, TotalBytesCount);
- return;
- }
- //记录包长度的字节
- byte[] TempHeadBytes = new byte[4];
- //包的第2到5位记录包的长度
- Buffer.BlockCopy(Totalbytes, 1, TempHeadBytes, 0, 4);
- //将字节转换为整型的长度
- int TempPackLen = BitConverter.ToInt32(TempHeadBytes, 0); //每个包的长度
- //如果包的长度加包头的长度大于接收的总字节数
- if ((TempPackLen + DataHeadLen) > TotalBytesCount)
- {
- DataBufferSizeLast = TotalBytesCount;
- DataBufferLast = new byte[TotalBytesCount];
- Buffer.BlockCopy(Totalbytes, 0, DataBufferLast, 0, TotalBytesCount);
- return;
- }
- byte[] TempPackBytes = new byte[TempPackLen];
- for (int i = 0; i < TempPackLen; i++)
- {
- TempPackBytes[i] = Totalbytes[i + DataHeadLen];
- }
- string receivedStr = System.Text.Encoding.Default.GetString(TempPackBytes);
- Rec_e.vDataPack = receivedStr;
- log.Info(receivedStr); //记录数据包日志
- RecEvent(this, Rec_e); //通知外部事件
- if (TotalBytesCount > DataHeadLen + TempPackLen)
- {
- byte[] Bytes = new byte[TotalBytesCount - DataHeadLen - TempPackLen];
- Buffer.BlockCopy(Totalbytes, DataHeadLen + TempPackLen, Bytes, 0, TotalBytesCount - DataHeadLen - TempPackLen);
- this.EncodingBytes(Bytes, TotalBytesCount - DataHeadLen - TempPackLen);
- }
- }
- catch (SocketException ex)
- {
- log.Info("EncodingBytes:" + ex.Message + "ErrorCode:" + ex.ErrorCode.ToString());
- }
- catch (Exception ex)
- {
- log.Info("EncodingBytes:" + ex.Message);
- }
- }
- //判断socket是否连接状态
- public bool IsConnected()
- {
- if (socket.Poll(-1, SelectMode.SelectRead))
- {
- byte[] tmp = new byte[1];
- int nRead = socket.Receive(tmp);
- if (nRead == 0)
- {
- //socket连接已断开
- return false;
- }
- }
- return true;
- }
- public bool Send(string vDataPack)
- {
- byte[] Ver = Encoding.Default.GetBytes(APIVersion.ToString());
- byte[] Len = new byte[4];
- Len = Encoding.Default.GetBytes(vDataPack.Length.ToString());
- byte[] msg = Encoding.Default.GetBytes(vDataPack);
- byte[] PackageBytes = new byte[msg.Length + DataHeadLen];
- byte[] b4 = Int32ToBytes((UInt32)(msg.Length));
- Ver.CopyTo(PackageBytes, 0);
- b4.CopyTo(PackageBytes, 1);
- msg.CopyTo(PackageBytes, DataHeadLen);
- //记录发送包日志
- log.Info(Encoding.Default.GetString(PackageBytes, 5, PackageBytes.Length - 5));
- try
- {
- int i = socket.Send(PackageBytes);
- return true;
- }
- catch //SocketException e
- {
- return false;
- }
- }
- // 4字节整型 --> 字节数组(Java队列用的序,低位在前,高位在后)
- public byte[] Int32ToBytes(UInt32 i)
- {
- byte[] bytes = new byte[4];
- bytes[0] = (byte)(i % 256); //每8位为一个字节
- bytes[1] = (byte)(i / 256);
- bytes[2] = (byte)(i / (65536));
- bytes[3] = (byte)(i / (16777216));
- return bytes;
- }
- }
- /// <summary>
- /// 服务端SOCKET类
- /// </summary>
- public class TcsServerCom
- {
- }
- }
- }
[C#]事件驱动的SOCKET类
最新推荐文章于 2024-07-09 23:49:10 发布