Skip to content

Commit 85d5921

Browse files
committed
udp/rudp. improve performance and prevent erros.
1 parent 20f5c6c commit 85d5921

File tree

3 files changed

+102
-192
lines changed

3 files changed

+102
-192
lines changed

src/rudp/partials/RUDP.ServerTo.cs

Lines changed: 42 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System;
22
using System.Collections.Generic;
33
using System.Linq;
4+
using System.Net;
45
using System.Net.Sockets;
56
using System.Text;
67
using System.Threading;
@@ -14,9 +15,8 @@ public partial class RUDP
1415
{
1516
private class ServerTo : IRUDP.ServerTo
1617
{
17-
private readonly List<Client> _clients;
18-
private readonly object _clientsLocker, _contentsLooker;
19-
private readonly List<(Host host, byte[] data)> _contents;
18+
private readonly List<Client> _clients = new List<Client>();
19+
private readonly object _clientsLocker = new object();
2020
private readonly Server _server;
2121
private bool _isOpeningOrClosing, _isClosed;
2222
private Socket _socket;
@@ -28,10 +28,6 @@ public ServerTo(Server server)
2828
{
2929
Host = Host.Default;
3030
_server = server;
31-
_clients = new List<Client>();
32-
_contents = new List<(Host host, byte[] data)>();
33-
_clientsLocker = new object();
34-
_contentsLooker = new object();
3531
_socket = null;
3632
_isOpeningOrClosing = false;
3733
_isClosed = true;
@@ -182,9 +178,10 @@ private void Broadcast(byte[] data, MessageType messageType)
182178
clients = _clients.ToArray();
183179
}
184180

185-
if (clients.Length > 0)
186-
foreach (var client in clients)
187-
client?.To.Data(data, messageType);
181+
if (clients.Length <= 0) return;
182+
183+
foreach (var client in clients)
184+
client?.To.Data(data, messageType);
188185
}
189186
catch (Exception e)
190187
{
@@ -203,9 +200,10 @@ private void Broadcast(string name, byte[] data, MessageType messageType)
203200
clients = _clients.ToArray();
204201
}
205202

206-
if (clients.Length > 0)
207-
foreach (var client in clients)
208-
client?.To.Data(data, messageType);
203+
if (clients.Length <= 0) return;
204+
205+
foreach (var client in clients)
206+
client?.To.Event(name, data, messageType);
209207
}
210208
catch (Exception e)
211209
{
@@ -218,131 +216,84 @@ private void InitAccept()
218216
{
219217
var length = (int)_socket.GetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveBuffer);
220218
var buffer = new byte[length > 0 ? length : 4096];
221-
var remoteEndPoint = Host.EndPoint;
222219

223-
AcceptUpdate();
220+
new Thread(Accept) { IsBackground = true }.Start();
224221

225-
new Thread(ContentUpdate) { IsBackground = true }.Start();
222+
return;
226223

227-
void AcceptUpdate()
224+
void Accept()
228225
{
229-
try
226+
while (IsOpened)
230227
{
231-
if (!IsOpened)
228+
try
232229
{
233-
Close();
234-
return;
235-
}
230+
var endpoint = Host.Default.EndPoint;
236231

237-
_socket.BeginReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref remoteEndPoint,
238-
AcceptCallback, null);
239-
}
240-
catch (Exception e)
241-
{
242-
NetlyEnvironment.Logger.Create(e);
243-
Close();
244-
}
245-
}
232+
var size = _socket.ReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None,
233+
ref endpoint);
246234

247-
void AcceptCallback(IAsyncResult result)
248-
{
249-
try
250-
{
251-
var size = _socket.EndReceiveFrom(result, ref remoteEndPoint);
235+
if (size <= 0) continue;
252236

253-
if (size > 0)
254-
{
255-
var data = new byte[size];
237+
var bytes = new byte[size];
256238

257-
Array.Copy(buffer, 0, data, 0, data.Length);
239+
Array.Copy(buffer, 0, bytes, 0, bytes.Length);
258240

259-
lock (_contentsLooker)
260-
{
261-
_contents.Add((new Host(remoteEndPoint), data));
262-
}
241+
EndAccept(endpoint, bytes);
242+
}
243+
catch (Exception e)
244+
{
245+
NetlyEnvironment.Logger.Create(e);
263246
}
264-
}
265-
catch (Exception e)
266-
{
267-
NetlyEnvironment.Logger.Create(e);
268247
}
269248

270-
AcceptUpdate();
249+
Close();
271250
}
272-
}
273251

274-
private void ContentUpdate()
275-
{
276-
while (IsOpened)
252+
void EndAccept(EndPoint endpoint, byte[] data)
277253
{
278-
// ReSharper disable once InconsistentlySynchronizedField
279-
if (_contents.Count <= 0) continue;
280-
281-
(Host host, byte[] data) value;
282-
Client client;
283-
284-
lock (_contentsLooker)
285-
{
286-
// recheck on thread safe area
287-
if (_contents.Count <= 0) continue;
288-
289-
// get first element
290-
value = _contents[0];
291-
292-
// remove first element
293-
_contents.RemoveAt(0);
294-
}
295-
296254
try
297255
{
256+
var host = new Host(endpoint);
257+
Client client;
258+
298259
lock (_clientsLocker)
299260
{
300261
// find client
301-
client = _clients.FirstOrDefault(x => value.host.Equals(x.Host));
262+
client = _clients.FirstOrDefault(x => host.Equals(x.Host));
302263
}
303264

304-
var buffer = value.data;
305-
306265
// use existent context
307266
if (client != null)
308267
{
309-
client.InjectBuffer(ref buffer);
310-
continue;
268+
client.InjectBuffer(ref data);
269+
return;
311270
}
312271

313272
#region Prevent Invalid Data
314273

315274
if (UseConnectionSecurity)
316275
{
317276
// detect expired data
318-
if (value.data.Length == 1)
277+
if (data.Length == 1)
319278
{
320-
if (value.data[0] == Channel.PingPackageBytes[0])
279+
if (data[0] == Channel.PingPackageBytes[0])
321280
{
322281
// this client already disconnected, can't receive ping
323-
continue;
282+
return;
324283
}
325284

326-
if (value.data[0] == Channel.ClosePackageBytes[0])
285+
if (data[0] == Channel.ClosePackageBytes[0])
327286
{
328287
// this client already disconnected, ignore this package
329-
continue;
288+
return;
330289
}
331290
}
332-
333-
// detect if is connection package
334-
/*
335-
if (!Channel.IsValidEntryPoint(value.data))
336-
{
337-
continue;
338-
}
339-
*/
340291
}
341292

342293
#endregion
343294

344295
// create new context
345-
client = new Client(value.host, _socket)
296+
client = new Client(host, _socket)
346297
{
347298
HandshakeTimeout = GetHandshakeTimeout(),
348299
NoResponseTimeout = GetNoResponseTimeout()
@@ -390,7 +341,7 @@ private void ContentUpdate()
390341

391342
if (client.IsOpened)
392343
{
393-
client.InjectBuffer(ref buffer);
344+
client.InjectBuffer(ref data);
394345
}
395346
}
396347
catch (Exception e)

src/udp/partials/UDP.ClientTo.cs

Lines changed: 27 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System;
22
using System.Net.Sockets;
33
using System.Text;
4+
using System.Threading;
45
using System.Threading.Tasks;
56
using Byter;
67
using Netly.Interfaces;
@@ -189,32 +190,16 @@ private void Send(Host host, byte[] bytes)
189190

190191
try
191192
{
193+
var data = new ArraySegment<byte>(bytes);
192194
if (_isServer)
193195
{
194-
// this way of send just work on windows and linux, except macOs (maybe iOs)
195-
_socket?.BeginSendTo
196-
(
197-
bytes,
198-
0,
199-
bytes.Length,
200-
SocketFlags.None,
201-
host.EndPoint,
202-
null,
203-
null
204-
);
196+
// this way of send just work on windows and linux, except macOS (maybe iOS)
197+
_socket?.SendToAsync(data, SocketFlags.None, host.EndPoint);
205198
}
206199
else
207200
{
208-
// this way of send just work on windows and linux, include macOs and iOs
209-
_socket?.BeginSend
210-
(
211-
bytes,
212-
0,
213-
bytes.Length,
214-
SocketFlags.None,
215-
null,
216-
null
217-
);
201+
// this way of send just work on windows and linux, include macOS and iOS
202+
_socket?.SendAsync(data, SocketFlags.None);
218203
}
219204
}
220205
catch (Exception e)
@@ -225,65 +210,42 @@ private void Send(Host host, byte[] bytes)
225210

226211
private void InitReceiver()
227212
{
228-
var endpoint = Host.EndPoint;
229-
230213
var buffer = new byte
231214
[
232215
// Maximum/Default receive buffer length.
233216
(int)_socket.GetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveBuffer)
234217
];
235218

236-
ReceiverUpdate();
237-
238-
void ReceiverUpdate()
239-
{
240-
if (!IsOpened)
241-
{
242-
Close();
243-
return;
244-
}
219+
new Thread(Receive) { IsBackground = true }.Start();
245220

246-
_socket.BeginReceiveFrom
247-
(
248-
buffer,
249-
0,
250-
buffer.Length,
251-
SocketFlags.None,
252-
ref endpoint,
253-
ReceiveCallback,
254-
null
255-
);
256-
}
221+
return;
257222

258-
void ReceiveCallback(IAsyncResult result)
223+
void Receive()
259224
{
260-
try
225+
while (IsOpened)
261226
{
262-
var size = _socket.EndReceiveFrom(result, ref endpoint);
263-
264-
if (size <= 0)
227+
try
265228
{
266-
if (IsOpened)
267-
ReceiverUpdate();
268-
else
269-
Close();
270-
271-
return;
272-
}
229+
var size = _socket.Receive(buffer, 0, buffer.Length, SocketFlags.None);
273230

274-
var data = new byte[size];
231+
if (size <= 0)
232+
{
233+
if (IsOpened) continue;
234+
else break;
235+
}
275236

276-
Array.Copy(buffer, 0, data, 0, data.Length);
237+
var bytes = new byte[size];
238+
Array.Copy(buffer, 0, bytes, 0, bytes.Length);
277239

278-
PushResult(ref data);
279-
280-
ReceiverUpdate();
281-
}
282-
catch (Exception e)
283-
{
284-
NetlyEnvironment.Logger.Create(e);
285-
Close();
240+
PushResult(ref bytes);
241+
}
242+
catch (Exception e)
243+
{
244+
NetlyEnvironment.Logger.Create(e);
245+
}
286246
}
247+
248+
Close();
287249
}
288250
}
289251

0 commit comments

Comments
 (0)