Skip to content

Commit 3c6cc36

Browse files
committed
Add UDP support.
1 parent 0df84c6 commit 3c6cc36

File tree

8 files changed

+75
-168
lines changed

8 files changed

+75
-168
lines changed

QpTestClient/QpTestClient.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
<ProjectReference Include="..\Quick.Protocol.Pipeline\Quick.Protocol.Pipeline.csproj" />
2727
<ProjectReference Include="..\Quick.Protocol.SerialPort\Quick.Protocol.SerialPort.csproj" />
2828
<ProjectReference Include="..\Quick.Protocol.Tcp\Quick.Protocol.Tcp.csproj" />
29+
<ProjectReference Include="..\Quick.Protocol.Udp\Quick.Protocol.Udp.csproj" />
2930
<ProjectReference Include="..\Quick.Protocol.WebSocket.Client\Quick.Protocol.WebSocket.Client.csproj" />
3031
<ProjectReference Include="..\Quick.Protocol\Quick.Protocol.csproj" />
3132
</ItemGroup>

QpTestClient/QuickConnectForm.Designer.cs

Lines changed: 30 additions & 34 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Quick.Protocol.AllClients/QpAllClients.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ public static void RegisterUriSchema()
1010
{
1111
Pipeline.QpPipelineClientOptions.RegisterUriSchema();
1212
Tcp.QpTcpClientOptions.RegisterUriSchema();
13+
Udp.QpUdpClientOptions.RegisterUriSchema();
1314
WebSocket.Client.QpWebSocketClientOptions.RegisterUriSchema();
1415
}
1516
}

Quick.Protocol.AllClients/Quick.Protocol.AllClients.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ WebSocket: ConnectionUriParser.Parse("ws://127.0.0.1:3001/qp");</Description>
3333
<ItemGroup>
3434
<ProjectReference Include="..\Quick.Protocol.Pipeline\Quick.Protocol.Pipeline.csproj" />
3535
<ProjectReference Include="..\Quick.Protocol.Tcp\Quick.Protocol.Tcp.csproj" />
36+
<ProjectReference Include="..\Quick.Protocol.Udp\Quick.Protocol.Udp.csproj" />
3637
<ProjectReference Include="..\Quick.Protocol.WebSocket.Client\Quick.Protocol.WebSocket.Client.csproj" />
3738
<ProjectReference Include="..\Quick.Protocol\Quick.Protocol.csproj" />
3839
</ItemGroup>

Quick.Protocol.Udp/QpUdpClient.cs

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,18 @@
33
using System.Collections.Generic;
44
using System.ComponentModel;
55
using System.IO;
6-
using System.Linq;
76
using System.Net;
87
using System.Net.Sockets;
98
using System.Text;
109
using System.Threading.Tasks;
10+
using UdpAsTcp;
1111

1212
namespace Quick.Protocol.Udp
1313
{
1414
[DisplayName("UDP")]
1515
public class QpUdpClient : QpClient
1616
{
17-
private UdpClient udpClient;
17+
private UdpAsTcpClient udpAsTcpClient;
1818
private QpUdpClientOptions options;
1919

2020
public QpUdpClient(QpUdpClientOptions options) : base(options)
@@ -24,26 +24,27 @@ public QpUdpClient(QpUdpClientOptions options) : base(options)
2424

2525
protected override async Task<Stream> InnerConnectAsync()
2626
{
27-
if (udpClient != null)
27+
if (udpAsTcpClient != null)
2828
Close();
2929
//开始连接
3030
if (string.IsNullOrEmpty(options.LocalHost))
31-
udpClient = new UdpClient();
31+
udpAsTcpClient = new UdpAsTcpClient();
3232
else
33-
udpClient = new UdpClient(new IPEndPoint(IPAddress.Parse(options.LocalHost), options.LocalPort));
34-
var remoteHostAddresses = await Dns.GetHostAddressesAsync(options.Host);
35-
var remoteEndPoint = new IPEndPoint(remoteHostAddresses.First(), options.Port);
36-
await TaskUtils.TaskWait(Task.Run(() => udpClient.Connect(remoteEndPoint)), options.ConnectionTimeout);
37-
return new UdpClientStream(udpClient, remoteEndPoint);
33+
udpAsTcpClient = new UdpAsTcpClient(new IPEndPoint(IPAddress.Parse(options.LocalHost), options.LocalPort));
34+
await TaskUtils.TaskWait(Task.Run(() => udpAsTcpClient.Connect(options.Host, options.Port)), options.ConnectionTimeout);
35+
36+
if (!udpAsTcpClient.Connected)
37+
throw new IOException($"Failed to connect to {options.Host}:{options.Port}.");
38+
return udpAsTcpClient.GetStream();
3839
}
3940

4041
public override void Disconnect()
4142
{
42-
if (udpClient != null)
43+
if (udpAsTcpClient != null)
4344
{
44-
udpClient.Close();
45-
udpClient.Dispose();
46-
udpClient = null;
45+
udpAsTcpClient.Close();
46+
udpAsTcpClient.Dispose();
47+
udpAsTcpClient = null;
4748
}
4849

4950
base.Disconnect();

Quick.Protocol.Udp/QpUdpServer.cs

Lines changed: 24 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,65 +1,58 @@
11
using Quick.Protocol.Utils;
22
using System;
33
using System.Collections.Generic;
4-
using System.IO;
54
using System.Net;
65
using System.Net.Sockets;
76
using System.Text;
87
using System.Threading;
98
using System.Threading.Tasks;
9+
using UdpAsTcp;
1010

1111
namespace Quick.Protocol.Udp
1212
{
1313
public class QpUdpServer : QpServer
1414
{
15-
private UdpClient udpServer;
15+
private UdpAsTcpListener udpAsTcpListener;
1616
private QpUdpServerOptions options;
17-
public IPEndPoint ListenEndPoint { get; private set; }
1817
public QpUdpServer(QpUdpServerOptions options) : base(options)
1918
{
2019
this.options = options;
2120
}
2221

2322
public override void Start()
2423
{
25-
ListenEndPoint = new IPEndPoint(options.Address, options.Port);
26-
udpServer = new UdpClient(ListenEndPoint);
24+
udpAsTcpListener = new UdpAsTcpListener(new IPEndPoint(options.Address, options.Port));
25+
udpAsTcpListener.Start();
2726
base.Start();
2827
}
2928

3029
public override void Stop()
3130
{
32-
udpServer?.Close();
33-
udpServer?.Dispose();
34-
udpServer = null;
31+
udpAsTcpListener?.Stop();
32+
udpAsTcpListener = null;
3533
base.Stop();
3634
}
3735

38-
protected override Task InnerAcceptAsync(CancellationToken token)
36+
protected override async Task InnerAcceptAsync(CancellationToken token)
3937
{
40-
return udpServer.ReceiveAsync().ContinueWith(task =>
41-
{
42-
if (task.IsCanceled)
43-
return;
44-
if (task.IsFaulted)
45-
return;
46-
var ret = task.Result;
47-
var remoteEndPoint = ret.RemoteEndPoint;
48-
var buffer = ret.Buffer;
38+
var udpAsTcpClient = await udpAsTcpListener.AcceptClientAsync();
4939

50-
try
51-
{
52-
var remoteEndPointStr = "UDP:" + remoteEndPoint.ToString();
53-
if (LogUtils.LogConnection)
54-
LogUtils.Log("[Connection]{0} connected.", remoteEndPointStr);
55-
OnNewChannelConnected(new UdpClientStream(udpServer, remoteEndPoint, buffer), remoteEndPointStr, token);
56-
}
57-
catch (Exception ex)
58-
{
59-
if (LogUtils.LogConnection)
60-
LogUtils.Log("[Connection]Init&Start Channel error,reason:{0}", ex.ToString());
61-
}
62-
});
40+
if (udpAsTcpClient == null)
41+
return;
42+
try
43+
{
44+
var remoteEndPointStr = "UDP:" + udpAsTcpClient.RemoteEndPoint.ToString();
45+
if (LogUtils.LogConnection)
46+
LogUtils.Log("[Connection]{0} connected.", remoteEndPointStr);
47+
OnNewChannelConnected(udpAsTcpClient.GetStream(), remoteEndPointStr, token);
48+
}
49+
catch (Exception ex)
50+
{
51+
if (LogUtils.LogConnection)
52+
LogUtils.Log("[Connection]Init&Start Channel error,reason:{0}", ex.ToString());
53+
try { udpAsTcpClient.Close(); }
54+
catch { }
55+
}
6356
}
6457
}
6558
}

Quick.Protocol.Udp/Quick.Protocol.Udp.csproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@
2121
</None>
2222
</ItemGroup>
2323

24+
<ItemGroup>
25+
<PackageReference Include="UdpAsTcp" Version="1.0.0" />
26+
</ItemGroup>
27+
2428
<ItemGroup>
2529
<ProjectReference Include="..\Quick.Protocol\Quick.Protocol.csproj" />
2630
</ItemGroup>

0 commit comments

Comments
 (0)