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<byte[], Socket> Event_ReceiveDataFromSocket;
|
/// <summary>
|
/// 发送SOCKET至远程服务端口
|
/// </summary>
|
/// <param name="i_data">数据包</param>
|
/// <param name="ipAddress">IP地址(192.168.1.1)</param>
|
/// <param name="port">端口</param>
|
/// <param name="isCompression">是否启用压缩</param>
|
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;
|
}
|
|
/// <summary>
|
/// 解压数据
|
/// </summary>
|
/// <param name="data"></param>
|
/// <returns></returns>
|
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;
|
}
|
}
|
}
|