- 1 public class TunNetWorkFrameHostedService : BackgroundService
- 2 {
- 3 private readonly string exchangeHostName = "";
- 4 private readonly int P2PPort = 61000;
- 5 protected readonly ILogger<TunNetWorkFrameHostedService> _logger;
- 6 public static TunNetWorkFrameHostedService Instance { get; private set; }
- 7 private readonly UdpClient udpClient;
- 8 private readonly System.Net.IPEndPoint remoteEndPoint = new System.Net.IPEndPoint(0, 0);
- 9 public TunNetWorkFrameHostedService(ILogger<TunNetWorkFrameHostedService> logger, IOptions<TunDriveConfig> tunDriveConfigOptions)
- 10 {
- 11 exchangeHostName = tunDriveConfigOptions.Value.DataExchangeHostName;
- 12 _logger = logger;
- 13 Instance = this;
- 14 udpClient = new UdpClient(0); if (Environment.OSVersion.Platform == PlatformID.Win32NT)
- 15 {
- 16 const int SIP_UDP_CONNRESET = -1744830452;
- 17 udpClient.Client.IOControl(SIP_UDP_CONNRESET, new byte[] { 0, 0, 0, 0 }, null);
- 18 }
- 19 }
- 20
- 21
- 22 protected override async Task ExecuteAsync(CancellationToken stoppingToken)
- 23 {
- 24 udpClient.BeginReceive(ReceiveCallback, udpClient);
- 25 while (!stoppingToken.IsCancellationRequested)
- 26 {
- 27 await udpClient.SendAsync(TunDriveHostedService.Instance.Id, exchangeHostName, P2PPort, stoppingToken).ConfigureAwait(false);
- 28 await Task.Delay(1000*30, stoppingToken).ConfigureAwait(false);
- 29 }
- 30 }
- 31 void ReceiveCallback(IAsyncResult ar)
- 32 {
- 33 System.Net.IPEndPoint remoteEndPoint = new System.Net.IPEndPoint(0, 0);
- 34 byte[] bytes = null;
- 35 try
- 36 {
- 37
- 38 bytes = udpClient.EndReceive(ar, ref remoteEndPoint);
- 39
- 40 }
- 41 finally
- 42 {
- 43 udpClient.BeginReceive(ReceiveCallback, udpClient);
- 44 }
- 45 if (bytes.Length == 4)
- 46 {
- 47 return;
- 48 }
- 49 if (bytes.Length == 5)
- 50 {
- 51 if (bytes[0] == 2)
- 52 {
- 53 P2PUDPSocketHostedService.Instance.TestP2P(bytes.Skip(1).ToArray(),false);
- 54 }
- 55 return;
- 56 }
- 57
- 58 TunDriveHostedService.Instance.WriteFrameBuffer(bytes);
- 59 }
- 60 public virtual async Task WriteFrameBufferAsync(Memory<byte> buffer, CancellationToken stoppingToken)
- 61 {
- 62 var destId = BitConverter.ToInt32(buffer.Slice(16, 4).ToArray(), 0);
- 63
- 64 var tunNetWorkFrameSend= P2PUDPSocketHostedService.Instance.GetP2PClient(buffer.Slice(16, 4).ToArray());
- 65 if (tunNetWorkFrameSend != null)
- 66 {
- 67 await tunNetWorkFrameSend.SendAsync(buffer, stoppingToken).ConfigureAwait(false);
- 68 return;
- 69 }
- 70 var bytes = new byte[buffer.Length + 8];
- 71 buffer.Slice(12, 8).CopyTo(bytes);
- 72 Array.Copy(buffer.ToArray(), 0,bytes,8,buffer.Length);
- 73 await udpClient.SendAsync(bytes, exchangeHostName, P2PPort, stoppingToken).ConfigureAwait(false);
- 74 //var destId = BitConverter.ToInt32(buffer.Slice(16, 4).ToArray(), 0);// string.Join(".", buffer.Slice(16, 4).ToArray());// span[16] << 24 | span[17] << 16 | span[18] << 8 | span[19];
- 75 //var sourceId = BitConverter.ToInt32(buffer.Slice(12, 4).ToArray(), 0);
- 76 //_logger.LogInformation($"{sourceId} 发送到{destId}");
- 77 }
- 78 /// <summary>
- 79 /// 发送打洞请求
- 80 /// </summary>
- 81 /// <param name="destId"></param>
- 82 /// <param name="stoppingToken"></param>
- 83 /// <returns></returns>
- 84 public virtual async Task SendP2PRequestAsync(byte[] destId, CancellationToken stoppingToken)
- 85 {
- 86 using (MemoryStream memoryStream = new MemoryStream()) {
- 87 memoryStream.Write(TunDriveHostedService.Instance.Id);
- 88 memoryStream.Write(destId);
- 89 memoryStream.WriteByte(2);
- 90 memoryStream.Write(TunDriveHostedService.Instance.Id);
- 91 await udpClient.SendAsync(memoryStream.ToArray(), exchangeHostName, P2PPort, stoppingToken).ConfigureAwait(false);
- 92 }
- 93
- 94 }
- 95 }