using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Threading;
using HslCommunication.BasicFramework;
using HslCommunication.Enthernet;
using HslCommunication.LogNet;
namespace HslCommunication.Core
{
/*******************************************************************************
*
* 网络通信类的基础类,提供所有相关的基础方法和功能
*
* Network communication base class of the class, provides the basis of all relevant methods and functions
*
*******************************************************************************/
#region 网络传输辅助类
///
/// 静态的方法支持类,提供一些网络的静态支持
///
public static class NetSupport
{
///
/// Socket传输中的缓冲池大小
///
internal const int SocketBufferSize = 4096;
///
/// 检查是否超时的静态方法
///
/// 数据封送对象
/// 超时的时间
internal static void ThreadPoolCheckConnect( HslTimeOut timeout, int millisecond )
{
while (!timeout.IsSuccessful)
{
if ((DateTime.Now - timeout.StartTime).TotalMilliseconds > millisecond)
{
// 连接超时或是验证超时
if (!timeout.IsSuccessful) timeout.WorkSocket?.Close( );
break;
}
Thread.Sleep( 100 );
}
}
internal static void ThreadPoolCheckTimeOut( object obj )
{
if (obj is HslTimeOut)
{
HslTimeOut timeout = (HslTimeOut)obj;
while (!timeout.IsSuccessful)
{
if ((DateTime.Now - timeout.StartTime).TotalMilliseconds > timeout.DelayTime)
{
// 连接超时或是验证超时
if (!timeout.IsSuccessful)
{
timeout.Operator?.Invoke( );
timeout.WorkSocket?.Close( );
}
break;
}
}
}
}
///
/// 读取socket数据的基础方法,只适合用来接收指令头,或是同步数据
///
/// 通信对象
/// 接收的长度
///
///
///
///
///
public static byte[] ReadBytesFromSocket( Socket socket, int receive )
{
return ReadBytesFromSocket( socket, receive, null, false, false );
}
///
/// 读取socket数据的基础方法,只适合用来接收指令头,或是同步数据
///
/// 通信对象
/// 接收的长度
/// 用于报告接收进度的对象
/// 是否按照百分比报告进度
/// 是否回发接收数据长度
///
///
///
///
///
public static byte[] ReadBytesFromSocket( Socket socket, int receive, Action report, bool reportByPercent, bool response )
{
byte[] bytes_receive = new byte[receive];
int count_receive = 0;
long percent = 0;
while (count_receive < receive)
{
// 分割成2KB来接收数据
int receive_length = (receive - count_receive) >= SocketBufferSize ? SocketBufferSize : (receive - count_receive);
count_receive += socket.Receive( bytes_receive, count_receive, receive_length, SocketFlags.None );
if (reportByPercent)
{
long percentCurrent = (long)count_receive * 100 / receive;
if (percent != percentCurrent)
{
percent = percentCurrent;
// 报告进度
report?.Invoke( count_receive, receive );
}
}
else
{
// 报告进度
report?.Invoke( count_receive, receive );
}
// 回发进度
if (response) socket.Send( BitConverter.GetBytes( (long)count_receive ) );
}
return bytes_receive;
}
///
/// 从socket套接字读取数据并写入流中,必然报告进度
///
/// 通信对象
/// stream
/// 接收的长度
/// 用于报告接收进度的对象
/// 是否按照百分比报告进度
///
///
///
///
///
internal static void WriteStreamFromSocket( Socket socket, Stream stream, long receive, Action report, bool reportByPercent )
{
byte[] buffer = new byte[SocketBufferSize];
long count_receive = 0;
long percent = 0;
while (count_receive < receive)
{
// 分割成4KB来接收数据
int current = socket.Receive( buffer, 0, SocketBufferSize, SocketFlags.None );
count_receive += current;
stream.Write( buffer, 0, current );
if (reportByPercent)
{
long percentCurrent = count_receive * 100 / receive;
if (percent != percentCurrent)
{
percent = percentCurrent;
// 报告进度
report?.Invoke( count_receive, receive );
}
}
else
{
// 报告进度
report?.Invoke( count_receive, receive );
}
// 回发进度
socket.Send( BitConverter.GetBytes( count_receive ) );
}
buffer = null;
}
///
/// 读取流并将数据写入socket
///
/// 文件流
/// 连接的套接字
/// 返回的文件长度
/// 发送的进度报告
///
///
///
///
///
internal static void WriteSocketFromStream( Socket socket, Stream stream, long length, Action report, bool reportByPercent )
{
byte[] buffer = new byte[SocketBufferSize];
long count_send = 0;
stream.Position = 0;
long percent = 0;
while (count_send < length)
{
int count = stream.Read( buffer, 0, SocketBufferSize );
count_send += count;
socket.Send( buffer, 0, count, SocketFlags.None );
while (count_send != BitConverter.ToInt64( ReadBytesFromSocket( socket, 8 ), 0 )) ;
long received = count_send;
if (reportByPercent)
{
long percentCurrent = received * 100 / length;
if (percent != percentCurrent)
{
percent = percentCurrent;
// 报告进度
report?.Invoke( received, length );
}
}
else
{
// 报告进度
report?.Invoke( received, length );
}
// 双重接收验证
if (count == 0)
{
break;
}
}
buffer = null;
}
}
#endregion
}