using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Net; using System.Net.Sockets; using System.IO; using System.Data; using System.Threading; using System.IO.Compression; namespace BatchService.Framework.Utility { public class SocketProcess { private bool _isCompression = false; private Socket _socket; private bool _isRunning = false; public event Action Event_ReceiveDataFromSocket; /// /// 发送SOCKET至远程服务端口 /// /// 数据包 /// IP地址(192.168.1.1) /// 端口 /// 是否启用压缩 public byte[] Send(byte[] i_data, string ipAddress, int port, bool isCompression) { //创建终结点EndPoint IPAddress ip = IPAddress.Parse(ipAddress); IPEndPoint ipe = new IPEndPoint(ip, port); //把ip和端口转化为IPEndPoint的实例 //LogHelper.Debug(string.Format("准备发送的数据包字节数:{0},IP:{1},Port:{2}", i_data.Length, ipAddress, port)); //创建Socket并连接到服务器 Socket c = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); // 创建Socket //LogHelper.Debug("Connecting..."); c.Connect(ipe); //连接到服务器 //向服务器发送信息 //LogHelper.Debug("Send message"); if (isCompression) { c.Send(this.Compress(i_data)); } else { c.Send(i_data); //发送信息 } //接受从服务器返回的信息 byte[] recvBytes = new byte[1024]; int bytes; bytes = c.Receive(recvBytes, recvBytes.Length, 0); //从服务器端接受返回信息 byte[] recvBytes2 = new byte[bytes]; Array.Copy(recvBytes, 0, recvBytes2, 0, bytes); //一定记着用完Socket后要关闭 c.Close(); return recvBytes2; } public void Listen(int i_port, bool isCompression) { _isCompression = isCompression; if (_isRunning) { LogHelper.Debug("监听服务已经在运行...不响应此次开启请求"); return; } try { LogHelper.Debug(string.Format("准备开启监听线程,端口号:{0}...", i_port)); _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); _socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, 5000); _socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 5000); _socket.NoDelay = false; IPEndPoint iep = new IPEndPoint(IPAddress.Any, i_port); _socket.Bind(iep); _isRunning = true; _socket.Listen(100); LogHelper.Debug(string.Format("端口号为:{0}的监听线程开启完成", i_port)); ThreadPool.QueueUserWorkItem(new WaitCallback(Accept)); } catch (Exception ex) { LogHelper.Error(ex.ToString()); } } protected virtual void Accept(object iar) { while (_isRunning) { try { ThreadPool.QueueUserWorkItem(new WaitCallback(AcceptConn), _socket.Accept()); } catch (Exception ex) { LogHelper.Error(ex.ToString()); } } } protected virtual void AcceptConn(object iar) { Socket client = iar as Socket; try { if (client == null) { return; } LogHelper.Debug(string.Format("收到{0}发来的数据请求", client.RemoteEndPoint.ToString())); int rec = 0; //缓存区2M byte[] tempData = new byte[1024 * 10]; int bytecount = 0; while (1 == 1) { try { bytecount = client.Receive(tempData, rec, tempData.Length - rec, SocketFlags.None); rec += bytecount; //接收到客户端关闭的消息 if (bytecount == 0) { client.Close(); LogHelper.Debug("未收到任何数据"); } Array.Resize(ref tempData, rec); if (_isCompression) { tempData = this.Decompress(tempData, tempData.Length); } LogHelper.Debug(string.Format("收到{0}字节", rec)); if (Event_ReceiveDataFromSocket != null) { Event_ReceiveDataFromSocket(tempData, client); } LogHelper.Debug("接收完成!"); } catch (Exception ex) { LogHelper.Error(string.Format("发生了错误:{0}", ex.ToString())); } finally { client.Shutdown(SocketShutdown.Both); } Thread.Sleep(500); break; } } catch (Exception ex) { LogHelper.Error(string.Format("来自的连接发生了错误:{0}", ex.ToString())); } } private byte[] Compress(byte[] i_byte_array) { byte[] t_bytes; MemoryStream t_MemoryStream = new MemoryStream(); GZipStream t_GZipStream = new GZipStream(t_MemoryStream, CompressionMode.Compress, true); t_GZipStream.Write(i_byte_array, 0, i_byte_array.Length); t_GZipStream.Close(); t_GZipStream.Dispose(); //必须把stream流关闭才能返回ms流数据,不然数据会不完整 //并且解压缩方法stream.Read(buffer, 0, buffer.Length)时会返回0 t_bytes = t_MemoryStream.ToArray(); t_MemoryStream.Close(); t_MemoryStream.Dispose(); return t_bytes; } /// /// 解压数据 /// /// /// private byte[] Decompress(byte[] i_byte_array, int i_byte_length) { byte[] t_bytes; MemoryStream t_MemoryStream = new MemoryStream(); t_MemoryStream.Write(i_byte_array, 0, i_byte_array.Length); t_MemoryStream.Position = 0; GZipStream t_GZipStream = new GZipStream(t_MemoryStream, CompressionMode.Decompress, true); byte[] t_buffer = new byte[i_byte_length]; MemoryStream t_temp_MemoryStream = new MemoryStream(); int t_read = t_GZipStream.Read(t_buffer, 0, t_buffer.Length); while (t_read > 0) { t_temp_MemoryStream.Write(t_buffer, 0, t_read); t_read = t_GZipStream.Read(t_buffer, 0, t_buffer.Length); } //必须把stream流关闭才能返回ms流数据,不然数据会不完整 t_GZipStream.Close(); t_GZipStream.Dispose(); t_MemoryStream.Close(); t_MemoryStream.Dispose(); t_bytes = t_temp_MemoryStream.ToArray(); t_temp_MemoryStream.Close(); t_temp_MemoryStream.Dispose(); return t_bytes; } } }