📄 filetransportorbase.cs
字号:
namespace Imps.Client.Core.P2P.FileTransportor
{
using Imps.Client.Core.P2P.ICE;
using NCindy;
using NCindy.Buffer;
using NCindy.Protocol.UDT;
using NCindy.Session.AIO;
using NCindy.Util.Logging;
using System;
using System.Diagnostics;
using System.Net.Sockets;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
public abstract class FileTransportorBase
{
public const int BlockSize = 0x100000;
private readonly object BlockTransportedSyncRoot;
protected bool canceled;
private int completedTimes;
protected const string CONFIRM_HEADER = "CONFIRM:";
protected readonly TransportingFile fileInfo;
public static readonly int HandshakeCmdLenght;
public const string HandshakeHeader = "HANDSHAKE:";
private static readonly ILogger log = LogFactory.CreateLogger(MethodBase.GetCurrentMethod().ReflectedType);
protected readonly Peer remotePeer;
protected readonly object sendSyncRoot;
public static readonly int ShutdownCmdLenght;
public const string ShutdownHeader = "SHUTDOWN:";
protected AsyncUDTSession tranSession;
private int transportedPrecent;
private long transportedSize;
private Stopwatch transportTime;
public event EventHandler<IntEventArgs> BlockTransported;
public event EventHandler TransportCompleted;
public event EventHandler TransportFailed;
static FileTransportorBase()
{
int length = Guid.NewGuid().ToString().Length;
ShutdownCmdLenght = "SHUTDOWN:".Length + length;
HandshakeCmdLenght = "HANDSHAKE:".Length + length;
}
protected FileTransportorBase(ISession session, Peer remotePeer)
{
this.sendSyncRoot = new object();
this.BlockTransportedSyncRoot = new object();
this.remotePeer = remotePeer;
this.tranSession = (AsyncUDTSession) session;
this.tranSession.ExceptionCaught += new EventHandler<ExceptionEventArgs>(this, (IntPtr) this.OnExceptionCaught);
this.tranSession.InnerSocket.SetSocketOption(SocketOptionLevel.Socket, UDTSocketOptionName.UDP_SNDBUF, 0x8000);
}
public FileTransportorBase(ISession session, Peer remotePeer, TransportingFile targetFile) : this(session, remotePeer)
{
this.fileInfo = targetFile;
}
public FileTransportorBase(ISession session, Peer remotePeer, string localFilePath, long completedSize) : this(session, remotePeer)
{
this.fileInfo = new TransportingFile(localFilePath, completedSize);
}
public FileTransportorBase(ISession session, Peer remotePeer, string localFilePath, long fileSize, string sourceFileName, long completedSize, string first100MMd5) : this(session, remotePeer)
{
this.fileInfo = new TransportingFile(localFilePath, fileSize, sourceFileName, completedSize, first100MMd5, remotePeer);
}
public void AsyncCancel()
{
try
{
using (AsyncUDTSession session = this.tranSession)
{
using (TransportingFile file = this.fileInfo)
{
if (log.IsInfoEnabled)
{
log.Info("Async cancel by: " + new StackTrace());
}
this.canceled = true;
}
}
}
catch
{
}
}
public void AsyncClose()
{
this.AsyncCancel();
}
public void AsyncStart()
{
this.transportTime = Stopwatch.StartNew();
this.Start(this.tranSession);
}
protected static string Buffer2String(IBuffer buffer)
{
return Encoding.UTF8.GetString(buffer.GetInnerByteArray(), 0, buffer.Limit);
}
protected void FireBlockTransported(long completedSize)
{
EventHandler<IntEventArgs> blockTransported = this.BlockTransported;
int num = 0;
try
{
Interlocked.Exchange(ref this.transportedSize, completedSize);
if (this.fileInfo.IsCompleted)
{
num = 100;
}
else
{
num = (int) ((100 * completedSize) / this.fileInfo.FileSize);
}
lock (this.BlockTransportedSyncRoot)
{
if ((((num - this.transportedPrecent) >= 1) || (num == 100)) && (blockTransported != null))
{
blockTransported.Invoke(this, new IntEventArgs(num));
}
}
}
catch
{
}
finally
{
this.transportedPrecent = num;
}
}
protected void FireTransportCompleted()
{
if ((this.fileInfo.CompletedSize >= this.fileInfo.FileSize) && (Interlocked.Increment(ref this.completedTimes) <= 1))
{
EventHandler transportCompleted = this.TransportCompleted;
if (transportCompleted != null)
{
try
{
using (TransportingFile file = this.fileInfo)
{
transportCompleted(this, EventArgs.Empty);
}
}
catch
{
}
}
}
}
protected void FireTransportFailed()
{
EventHandler transportFailed = this.TransportFailed;
if (transportFailed != null)
{
try
{
transportFailed(this, EventArgs.Empty);
}
catch
{
}
}
}
public float GetTransportRate(long lastComplete)
{
if (this.transportedSize >= lastComplete)
{
return (float) ((0x3e8 * (this.transportedSize - lastComplete)) / this.transportTime.get_ElapsedMilliseconds());
}
return 0f;
}
private void OnExceptionCaught(object sender, ExceptionEventArgs e)
{
log.Error(string.Format("Session form {0} to {1} has exception.", P2PManager.Instace.LocalPeer.Sid, this.remotePeer.Sid), e.Cause);
if (e.Cause is SocketException)
{
this.tranSession.Close();
this.FireTransportFailed();
}
}
protected abstract void OnObjectReceived(object sender, SessionEventArgs e);
protected void SendACK(string initOffer)
{
IBuffer buffer = String2Buffer(initOffer + this.remotePeer.PeerToken);
lock (this.sendSyncRoot)
{
this.tranSession.Send(buffer);
}
}
protected abstract void Start(object obj);
protected static IBuffer String2Buffer(string token)
{
IBuffer buffer = BufferFactory.GetBuffer(token.Length * 2);
int num = Encoding.UTF8.GetBytes(token, 0, token.Length, buffer.GetInnerByteArray(), 0);
buffer.Limit = num;
return buffer;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -