NetUtils.cs 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. using STUN.Client;
  2. using STUN.StunResult;
  3. using System;
  4. using System.Diagnostics;
  5. using System.Linq;
  6. using System.Net;
  7. using System.Net.Sockets;
  8. namespace STUN.Utils
  9. {
  10. public static class NetUtils
  11. {
  12. public const string DefaultLocalEnd = @"0.0.0.0:0";
  13. public static IPEndPoint ParseEndpoint(string str)
  14. {
  15. //TODO:IPv6
  16. var ipPort = str.Trim().Split(':');
  17. if (ipPort.Length == 2)
  18. {
  19. if (IPAddress.TryParse(ipPort[0], out var ip))
  20. {
  21. if (ushort.TryParse(ipPort[1], out var port))
  22. {
  23. return new IPEndPoint(ip, port);
  24. }
  25. }
  26. }
  27. return null;
  28. }
  29. public static (string, string, string) NatTypeTestCore(string local, string server, ushort port)
  30. {
  31. try
  32. {
  33. if (string.IsNullOrWhiteSpace(server))
  34. {
  35. Debug.WriteLine(@"[ERROR]: Please specify STUN server !");
  36. return (string.Empty, DefaultLocalEnd, string.Empty);
  37. }
  38. using var client = new StunClient3489(server, port, ParseEndpoint(local));
  39. var result = (ClassicStunResult)client.Query();
  40. return (
  41. result.NatType.ToString(),
  42. $@"{client.LocalEndPoint}",
  43. $@"{result.PublicEndPoint}"
  44. );
  45. }
  46. catch (Exception ex)
  47. {
  48. Debug.WriteLine($@"[ERROR]: {ex}");
  49. return (string.Empty, DefaultLocalEnd, string.Empty);
  50. }
  51. }
  52. public static (byte[], IPEndPoint, IPAddress) UdpReceive(this UdpClient client, byte[] bytes, IPEndPoint remote, EndPoint receive)
  53. {
  54. var localEndPoint = (IPEndPoint)client.Client.LocalEndPoint;
  55. Debug.WriteLine($@"{localEndPoint} => {remote} {bytes.Length} 字节");
  56. client.Send(bytes, bytes.Length, remote);
  57. var res = new byte[ushort.MaxValue];
  58. var flag = SocketFlags.None;
  59. var length = client.Client.ReceiveMessageFrom(res, 0, res.Length, ref flag, ref receive, out var ipPacketInformation);
  60. var local = ipPacketInformation.Address;
  61. Debug.WriteLine($@"{(IPEndPoint)receive} => {local} {length} 字节");
  62. return (res.Take(length).ToArray(),
  63. (IPEndPoint)receive
  64. , local);
  65. }
  66. }
  67. }