Bläddra i källkod

Udp ReceiveMessageFromAsync

Bruce Wayne 4 år sedan
förälder
incheckning
66d2b4a3cc
3 ändrade filer med 33 tillägg och 15 borttagningar
  1. 3 10
      STUN/Proxy/NoneUdpProxy.cs
  2. 4 5
      STUN/Proxy/Socks5UdpProxy.cs
  3. 26 0
      STUN/Utils/NetUtils.cs

+ 3 - 10
STUN/Proxy/NoneUdpProxy.cs

@@ -1,3 +1,4 @@
+using STUN.Utils;
 using System;
 using System.Diagnostics;
 using System.Linq;
@@ -45,17 +46,9 @@ namespace STUN.Proxy
 			await _udpClient.SendAsync(bytes, bytes.Length, remote);
 
 			var res = new byte[ushort.MaxValue];
-			var flag = SocketFlags.None;
 
-			var length = _udpClient.Client.ReceiveMessageFrom(res, 0, res.Length, ref flag, ref receive, out var ipPacketInformation);
-
-			var local = ipPacketInformation.Address;
-
-			Debug.WriteLine($@"{(IPEndPoint)receive} => {local} {length} 字节");
-
-			return (res.Take(length).ToArray(),
-					(IPEndPoint)receive
-					, local);
+			var (local, length, rec) = await _udpClient.Client.ReceiveMessageFromAsync(receive, res, SocketFlags.None);
+			return (res.Take(length).ToArray(), rec, local);
 		}
 
 		public void Dispose()

+ 4 - 5
STUN/Proxy/Socks5UdpProxy.cs

@@ -188,7 +188,7 @@ namespace STUN.Proxy
 			var state = _assoc.GetState();
 			if (state != TcpState.Established)
 			{
-				throw new InvalidOperationException("No UDP association, maybe already disconnected or not connected");
+				throw new InvalidOperationException(@"No UDP association, maybe already disconnected or not connected");
 			}
 
 			var remoteBytes = GetEndPointByte(remote);
@@ -198,9 +198,8 @@ namespace STUN.Proxy
 
 			await _udpClient.SendAsync(proxyBytes, proxyBytes.Length, _assocEndPoint);
 			var res = new byte[ushort.MaxValue];
-			var flag = SocketFlags.None;
-			EndPoint ep = new IPEndPoint(0, 0);
-			var length = _udpClient.Client.ReceiveMessageFrom(res, 0, res.Length, ref flag, ref ep, out var ipPacketInformation);
+
+			var (local, length, _) = await _udpClient.Client.ReceiveMessageFromAsync(_assocEndPoint!, res, SocketFlags.None);
 
 			if (res[0] != 0 || res[1] != 0 || res[2] != 0)
 			{
@@ -219,7 +218,7 @@ namespace STUN.Proxy
 			return (
 				ret,
 				new IPEndPoint(ip, port),
-				ipPacketInformation.Address);
+				local);
 		}
 
 		public Task DisconnectAsync()

+ 26 - 0
STUN/Utils/NetUtils.cs

@@ -1,7 +1,10 @@
+using System;
+using System.Diagnostics;
 using System.Linq;
 using System.Net;
 using System.Net.NetworkInformation;
 using System.Net.Sockets;
+using System.Threading.Tasks;
 
 namespace STUN.Utils
 {
@@ -53,5 +56,28 @@ namespace STUN.Utils
 				.SingleOrDefault(x => x.LocalEndPoint.Equals(tcpClient.Client.LocalEndPoint));
 			return foo?.State ?? TcpState.Unknown;
 		}
+
+		public static async Task<(IPAddress, int, IPEndPoint)> ReceiveMessageFromAsync(this Socket client, EndPoint receive, byte[] array, SocketFlags flag)
+		{
+			var tcs = new TaskCompletionSource<(IPAddress, int, IPEndPoint)>(TaskCreationOptions.RunContinuationsAsynchronously);
+			_ = Task.Run(() =>
+			{
+				try
+				{
+					var length = client.ReceiveMessageFrom(array, 0, array.Length, ref flag, ref receive, out var ipPacketInformation);
+
+					var local = ipPacketInformation.Address;
+
+					Debug.WriteLine($@"{(IPEndPoint)receive} => {local} {length} 字节");
+					tcs.SetResult((local, length, (IPEndPoint)receive));
+				}
+				catch (Exception ex)
+				{
+					tcs.SetException(ex);
+				}
+			});
+
+			return await tcs.Task;
+		}
 	}
 }