Skip to content

Commit 03892e6

Browse files
committed
fix 多次回调close的bug,本地监听同时监听IPV4和IPV6端口
1 parent c1e7639 commit 03892e6

File tree

2 files changed

+113
-46
lines changed

2 files changed

+113
-46
lines changed

Network.cs

+106-39
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
using UnityObject = UnityEngine.Object;
1111

1212
namespace TinyNet
13-
{
13+
{
1414
#region 发送和接收缓冲区
1515
/// <summary>
1616
/// 填充数据包
@@ -65,8 +65,8 @@ public static BufferSegment Make(byte onebyte)
6565
};
6666
return seg;
6767
}
68-
}
69-
68+
}
69+
7070
/// <summary>
7171
/// 复用缓冲区
7272
/// </summary>
@@ -192,9 +192,9 @@ public void Reset()
192192
_offset = 0;
193193
_length = 0;
194194
}
195-
}
195+
}
196196
#endregion
197-
197+
198198
#region 解析网络请求
199199
/// <summary>
200200
/// 基础请求类
@@ -239,8 +239,8 @@ public virtual void Reset()
239239
{
240240
buffer.Reset();
241241
}
242-
}
243-
242+
}
243+
244244
/// <summary>
245245
/// 无ID分组
246246
/// </summary>
@@ -259,8 +259,8 @@ protected virtual void Handle(NetHandler handler, T t)
259259
}
260260

261261
public static event Action<NetHandler, T> DefaultHandler;
262-
}
263-
262+
}
263+
264264
/// <summary>
265265
/// 按ID分组
266266
/// </summary>
@@ -296,9 +296,9 @@ public static Dictionary<TKey, Action<NetHandler, T>> Handlers
296296
}
297297
}
298298
public static event Action<NetHandler, TKey, T> DefaultHandler;
299-
}
299+
}
300300
#endregion
301-
301+
302302
#region 设置相关
303303
public class Settings
304304
{
@@ -322,9 +322,9 @@ public Settings()
322322
capacity = 2 << 24;
323323
worklimit = 4;
324324
}
325-
}
325+
}
326326
#endregion
327-
327+
328328
/// <summary>
329329
/// 网络连接抽象句柄
330330
/// </summary>
@@ -340,8 +340,8 @@ public abstract class NetHandler
340340
public abstract IPEndPoint Local { get; }
341341
public abstract short TTL { get; set; }
342342
public abstract bool NoDelay { get; set; }
343-
}
344-
343+
}
344+
345345
/// <summary>
346346
/// 网络管理全局接口
347347
/// </summary>
@@ -353,18 +353,19 @@ public abstract class NetManager : IDisposable
353353
private readonly Queue<NetHandlerImpl> workqueue = new Queue<NetHandlerImpl>();
354354
private readonly Dictionary<NetHandlerImpl, bool> workindex = new Dictionary<NetHandlerImpl, bool>();
355355
private readonly Dictionary<int, Control> listens = new Dictionary<int, Control>();
356+
private readonly Dictionary<int, Control> listensv6 = new Dictionary<int, Control>();
356357
private readonly Dictionary<NetHandlerImpl, bool> sockets = new Dictionary<NetHandlerImpl, bool>();
357358

358-
private static readonly Dictionary<NetManager, bool> managers = new Dictionary<NetManager, bool>();
359-
359+
private static readonly Dictionary<NetManager, bool> managers = new Dictionary<NetManager, bool>();
360+
360361
#region 内部使用的类
361362
private class Control
362363
{
363364
public bool running;
364365
public Action<NetHandler> action;
365-
}
366+
}
366367
#endregion
367-
368+
368369
protected NetManager(Settings settings)
369370
{
370371
this.settings = settings;
@@ -383,7 +384,7 @@ public void Listen(int port, Action<NetHandler> callback)
383384
{
384385
if (!running)
385386
throw new ObjectDisposedException(ToString());
386-
new Thread(delegate ()
387+
new Thread(delegate()
387388
{
388389
Thread.CurrentThread.Name = "Network Server";
389390
TcpListener server = new TcpListener(IPAddress.Any, port);
@@ -430,6 +431,53 @@ public void Listen(int port, Action<NetHandler> callback)
430431
}
431432
server.Stop();
432433
}).Start();
434+
new Thread(delegate()
435+
{
436+
Thread.CurrentThread.Name = "Network Server";
437+
TcpListener server = new TcpListener(IPAddress.IPv6Any, port);
438+
server.Start();
439+
Control ctrl;
440+
lock (listensv6)
441+
{
442+
if (listensv6.TryGetValue(port, out ctrl))
443+
{
444+
ctrl.running = true;
445+
}
446+
else
447+
{
448+
ctrl = new Control { running = true };
449+
listensv6[port] = ctrl;
450+
}
451+
}
452+
ctrl.action = callback;
453+
while (running)
454+
{
455+
if (!server.Server.Poll(1000, SelectMode.SelectRead))
456+
{
457+
if (!ctrl.running)
458+
break;
459+
continue;
460+
}
461+
if (!server.Pending())
462+
break;
463+
NetHandlerImpl socket = new NetHandlerImpl(server.AcceptSocket(), this);
464+
socket.Socket.Blocking = false;
465+
socket.OnConnected();
466+
Loop.Run(() =>
467+
{
468+
ctrl.action(socket);
469+
});
470+
}
471+
lock (listensv6)
472+
{
473+
Control ctrlnow;
474+
if (listensv6.TryGetValue(port, out ctrlnow) && ctrlnow == ctrl)
475+
{
476+
listensv6.Remove(port);
477+
}
478+
}
479+
server.Stop();
480+
}).Start();
433481
}
434482

435483
public void Stop(int port)
@@ -445,6 +493,15 @@ public void Stop(int port)
445493
listens.Remove(port);
446494
}
447495
}
496+
lock (listensv6)
497+
{
498+
Control ctrl;
499+
if (listensv6.TryGetValue(port, out ctrl))
500+
{
501+
ctrl.running = false;
502+
listensv6.Remove(port);
503+
}
504+
}
448505
}
449506

450507
public NetHandler Connect(string hostport, int timeout)
@@ -533,8 +590,8 @@ public void Dispose()
533590
public void Close()
534591
{
535592
Dispose();
536-
}
537-
593+
}
594+
538595
#region 连接
539596
private void ConnectImpl(string host, int port, int timeout, Action<NetHandler, Exception> callback)
540597
{
@@ -604,9 +661,9 @@ private void ConnectImpl(string host, int port, int timeout, Action<NetHandler,
604661
callback(null, e);
605662
}
606663
}, null);
607-
}
664+
}
608665
#endregion
609-
666+
610667
private void SendQueue(NetHandlerImpl handler)
611668
{
612669
lock (workqueue)
@@ -625,7 +682,7 @@ private void SendQueue(NetHandlerImpl handler)
625682
Interlocked.Decrement(ref workcount);
626683
return;
627684
}
628-
new Thread(delegate ()
685+
new Thread(delegate()
629686
{
630687
Thread.CurrentThread.Name = "Network Write";
631688
while (running)
@@ -671,27 +728,30 @@ private void SendQueue(NetHandlerImpl handler)
671728
}
672729
}
673730
}).Start();
674-
}
675-
731+
}
732+
676733
#region 网络连接的具体类
677734
private class NetHandlerImpl : NetHandler
678735
{
679736
public readonly Socket Socket;
680737

681738
public readonly ByteBuffer buffer = new ByteBuffer();
682739
private readonly NetManager manager;
740+
private int closed;
683741
private Request request;
684742

685743
public NetHandlerImpl(AddressFamily family, NetManager manager)
686744
{
687745
this.manager = manager;
746+
this.closed = 0;
688747
Socket = new Socket(family, SocketType.Stream, ProtocolType.Tcp);
689748
Socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Linger, new LingerOption(false, 0));
690749
}
691750

692751
public NetHandlerImpl(Socket socket, NetManager manager)
693752
{
694753
this.manager = manager;
754+
this.closed = 0;
695755
Socket = socket;
696756
Socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Linger, new LingerOption(false, 0));
697757
}
@@ -702,7 +762,7 @@ public void OnConnected()
702762
{
703763
manager.sockets.Add(this, true);
704764
}
705-
new Thread(delegate ()
765+
new Thread(delegate()
706766
{
707767
Thread.CurrentThread.Name = "Network Read";
708768
byte[] bytes = new byte[64 * 1024];
@@ -795,7 +855,8 @@ public void OnConnected()
795855

796856
public override void Close()
797857
{
798-
Socket.Close();
858+
if (Interlocked.CompareExchange(ref closed, 1, 0) != 0)
859+
return;
799860
lock (manager.sockets)
800861
{
801862
manager.sockets.Remove(this);
@@ -805,12 +866,14 @@ public override void Close()
805866
Loop.Run(() =>
806867
{
807868
if (manager.settings.events.close != null)
808-
{
809869
manager.settings.events.close(this);
810-
manager.settings.events.close = null;
811-
}
870+
Socket.Close();
812871
});
813872
}
873+
else
874+
{
875+
Socket.Close();
876+
}
814877
}
815878

816879
public override bool Send(BufferSegment seg)
@@ -948,7 +1011,7 @@ private void OnReceive(byte[] bytes, int length)
9481011
size = length - offset;
9491012
Request old = request;
9501013
request = manager.NewRequest();
951-
Loop.Run(delegate ()
1014+
Loop.Run(delegate()
9521015
{
9531016
if (manager.settings.events.request != null)
9541017
{
@@ -961,18 +1024,22 @@ private void OnReceive(byte[] bytes, int length)
9611024
}
9621025
catch (Exception e)
9631026
{
964-
Socket.Close();
9651027
if (manager.settings.events.close != null)
9661028
{
967-
Loop.Run(delegate ()
1029+
Loop.Run(delegate()
9681030
{
9691031
if (manager.settings.events.close != null)
9701032
manager.settings.events.close(this);
1033+
Socket.Close();
9711034
});
9721035
}
1036+
else
1037+
{
1038+
Socket.Close();
1039+
}
9731040
if (manager.settings.events.exception != null)
9741041
{
975-
Loop.Run(delegate ()
1042+
Loop.Run(delegate()
9761043
{
9771044
if (manager.settings.events.exception != null)
9781045
manager.settings.events.exception(this, e);
@@ -983,9 +1050,9 @@ private void OnReceive(byte[] bytes, int length)
9831050
}
9841051

9851052
protected abstract Request NewRequest();
986-
protected abstract void ReleaseRequest(Request request);
1053+
protected abstract void ReleaseRequest(Request request);
9871054
#endregion
988-
1055+
9891056
#region 主循环调用
9901057
private static class Loop
9911058
{
@@ -1115,7 +1182,7 @@ void OnApplicationQuit()
11151182
}
11161183
}
11171184
}
1118-
}
1185+
}
11191186
#endregion
11201187
}
11211188

UnitTest/TestCase.cs

+7-7
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,13 @@ public static NetManager NetMgr
2525
}
2626
},
2727
read = (handler, len) => {
28-
Debug.Log("read " + len);
28+
Debug.Log("read " + len);
2929
},
30-
close = (handler) => {
31-
Debug.Log("handler close");
30+
close = (handler) => {
31+
Debug.Log("handler close");
3232
},
3333
write = (handler, len) => {
34-
Debug.Log("write " + len);;
34+
Debug.Log("write " + len);
3535
}
3636
}
3737
};
@@ -43,7 +43,7 @@ public static NetManager NetMgr
4343

4444
public static void StartListen(int port)
4545
{
46-
NetMgr.Listen(port, delegate (NetHandler socket)
46+
NetMgr.Listen(port, delegate(NetHandler socket)
4747
{
4848
Debug.Log("New Connection");
4949
});
@@ -69,8 +69,8 @@ public static void StartConnect(string ipport)
6969
public static void Main(string[] args)
7070
{
7171
NetManager.Initialize();
72-
StartListen(12306);
73-
StartConnect("127.0.0.1:12306");
72+
StartListen(12306);
73+
StartConnect("localhost:12306");
7474
}
7575
}
7676
}

0 commit comments

Comments
 (0)