📄 p2pmanager.cs
字号:
namespace Imps.Client.Core.P2P.FileTransportor
{
using Imps.Client;
using Imps.Client.Core;
using Imps.Client.Core.P2P.BlockingTransportor;
using Imps.Client.Core.P2P.ICE;
using NCindy.Util.Logging;
using System;
using System.Collections.Generic;
using System.Net.Sockets;
using System.Text.RegularExpressions;
using System.Threading;
using System.Windows.Forms;
public class P2PManager
{
private int currentTransportingID;
private static readonly P2PManager instace = new P2PManager();
private User localUser;
private static readonly ILogger log = LogFactory.CreateLogger(MethodBase.GetCurrentMethod().ReflectedType);
private Listener mclistener;
private const string StunGroups = @"([^:;]+):(\d+);?";
private readonly Regex stunGroupsRegex = new Regex(@"([^:;]+):(\d+);?");
private readonly List<StunUnit> stunServers = new List<StunUnit>();
private string stunUrls;
private readonly Dictionary<byte, TransportingFile> transportingFiles = new Dictionary<byte, TransportingFile>();
private const int TryTcpConnectTimeout = 0x3e8;
private P2PManager()
{
Application.ApplicationExit += new EventHandler(this.OnApplicationExit);
}
public byte Add(TransportingFile file)
{
lock (this.transportingFiles)
{
byte num;
do
{
num = (byte) (this.currentTransportingID++ % 0xff);
}
while (!this.transportingFiles.ContainsKey(num));
this.transportingFiles.Add(num, file);
return num;
}
}
public TransportingFile GetFile(byte id)
{
if (!this.transportingFiles.ContainsKey(id))
{
return null;
}
lock (this.transportingFiles)
{
if (!this.transportingFiles.ContainsKey(id))
{
return null;
}
return this.transportingFiles.get_Item(id);
}
}
private void OnApplicationExit(object sender, EventArgs e)
{
if (this.mclistener != null)
{
this.mclistener.Stop();
}
}
private void OnLocalUserStatusChanged(object sender, UserSatusChangedEventArgs e)
{
if (e.NewStatus == UserAccountStatus.Logon)
{
if (e.OldStatus != UserAccountStatus.Logon)
{
this.mclistener = new Listener(this.localUser);
this.mclistener.Start();
}
}
else if (e.OldStatus == UserAccountStatus.Logon)
{
this.mclistener.Stop();
}
}
private void ParseStunUrls()
{
if (!string.IsNullOrEmpty(this.stunUrls))
{
foreach (Match match in this.stunGroupsRegex.Matches(this.stunUrls))
{
try
{
this.stunServers.Add(new StunUnit(match.Groups[1].Value, int.Parse(match.Groups[2].Value)));
continue;
}
catch
{
continue;
}
}
}
}
public void Remvoe(byte id)
{
lock (this.transportingFiles)
{
this.transportingFiles.Remove(id);
}
}
public PunchingResult TryTcpConnect(Peer remote, byte[] token)
{
Peer peer = this.mclistener.IsInSameLan(remote);
if (peer != null)
{
Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
ManualResetEvent mre = new ManualResetEvent(false);
s.BeginConnect(peer.FirstEndPoint, delegate (IAsyncResult asyncResult) {
try
{
s.EndConnect(asyncResult);
byte[] buffer = token;
for (int j = 0; i < buffer1.Length; i += s.Send(buffer1, i, buffer1.Length - i, SocketFlags.None))
{
}
mre.Set();
}
catch
{
}
}, null);
if (mre.WaitOne(0x3e8, true))
{
return new TcpConnectingResult(this.LocalPeer, peer, s);
}
s.Close();
}
return null;
}
private StunUnit FirstStunUnit
{
get
{
if (this.stunServers.get_Count() > 0)
{
return this.stunServers.get_Item(0);
}
lock (this.stunServers)
{
if (this.stunServers.get_Count() <= 0)
{
this.stunUrls = this.localUser.Configuration.SystemSetting.ServerUriSetting.UriStun;
if (string.IsNullOrEmpty(this.stunUrls))
{
return null;
}
this.ParseStunUrls();
if (this.stunServers.get_Count() <= 0)
{
goto Label_00A2;
}
}
return this.stunServers.get_Item(0);
Label_00A2:;
}
return null;
}
}
public static P2PManager Instace
{
get
{
return instace;
}
}
public Listener LanPeerListener
{
get
{
return this.mclistener;
}
}
public Peer LocalPeer
{
get
{
return new Peer(this.localUser.Sid);
}
}
public User LocalUser
{
get
{
return this.localUser;
}
set
{
if ((value != null) && !object.Equals(this.localUser, value))
{
if (this.localUser != null)
{
if (this.mclistener != null)
{
this.mclistener.Stop();
}
this.localUser.StatusChanged -= new EventHandler<UserSatusChangedEventArgs>(this, (IntPtr) this.OnLocalUserStatusChanged);
}
this.localUser = value;
this.localUser.StatusChanged += new EventHandler<UserSatusChangedEventArgs>(this, (IntPtr) this.OnLocalUserStatusChanged);
}
}
}
public string StunHost
{
get
{
if (this.FirstStunUnit != null)
{
return this.FirstStunUnit.Host;
}
if (StunUnit.Debug != null)
{
return StunUnit.Debug.Host;
}
return "stunserver.org";
}
}
public int StunPort
{
get
{
if (this.FirstStunUnit != null)
{
return this.FirstStunUnit.Port;
}
if (StunUnit.Debug != null)
{
return StunUnit.Debug.Port;
}
return 0xd96;
}
}
internal class StunUnit
{
private static readonly P2PManager.StunUnit _debug = GetDebugStunUnit();
private static readonly P2PManager.StunUnit _default = new P2PManager.StunUnit("stunserver.org", 0xd96);
public const string DefaultHost = "stunserver.org";
public const int DefaultPort = 0xd96;
private readonly string host;
private readonly int port;
public StunUnit(string host, int port)
{
this.host = host;
this.port = port;
}
private static P2PManager.StunUnit GetDebugStunUnit()
{
int port;
if (string.IsNullOrEmpty(Imps.Client.Core.FixedClientSetting.Instance.Debug_STUNServerUrl))
{
return null;
}
string[] textArray = Imps.Client.Core.FixedClientSetting.Instance.Debug_STUNServerUrl.Split(new char[] { ':' });
if (textArray.Length != 2)
{
return null;
}
if (!int.TryParse(textArray[1], ref port))
{
port = 0xd96;
}
return new P2PManager.StunUnit(textArray[0], port);
}
public static P2PManager.StunUnit Debug
{
get
{
return _debug;
}
}
public static P2PManager.StunUnit Default
{
get
{
return _default;
}
}
public string Host
{
get
{
return this.host;
}
}
public int Port
{
get
{
return this.port;
}
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -