USocket.cs 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. using System;
  2. using System.Collections.Generic;
  3. namespace Base
  4. {
  5. internal class BufferInfo
  6. {
  7. public byte[] Buffer { get; set; }
  8. public byte ChannelID { get; set; }
  9. public PacketFlags Flags { get; set; }
  10. }
  11. internal sealed class USocket: IDisposable
  12. {
  13. private readonly UPoller poller;
  14. private readonly Queue<byte[]> recvQueue = new Queue<byte[]>();
  15. private readonly Queue<BufferInfo> sendQueue = new Queue<BufferInfo>();
  16. private bool isConnected;
  17. private string remoteAddress;
  18. public Action Disconnect;
  19. public USocket(IntPtr peerPtr, UPoller poller)
  20. {
  21. this.poller = poller;
  22. this.PeerPtr = peerPtr;
  23. }
  24. public USocket(UPoller poller)
  25. {
  26. this.poller = poller;
  27. }
  28. private void Dispose(bool disposing)
  29. {
  30. if (this.PeerPtr == IntPtr.Zero)
  31. {
  32. return;
  33. }
  34. poller.USocketManager.Remove(this.PeerPtr);
  35. NativeMethods.ENetPeerDisconnectNow(this.PeerPtr, 0);
  36. this.PeerPtr = IntPtr.Zero;
  37. }
  38. ~USocket()
  39. {
  40. this.Dispose(false);
  41. }
  42. public void Dispose()
  43. {
  44. this.Dispose(true);
  45. }
  46. public IntPtr PeerPtr { get; set; }
  47. public string RemoteAddress
  48. {
  49. get
  50. {
  51. return remoteAddress;
  52. }
  53. }
  54. public Queue<byte[]> RecvQueue
  55. {
  56. get
  57. {
  58. return recvQueue;
  59. }
  60. }
  61. public void ConnectAsync(string host, ushort port)
  62. {
  63. this.remoteAddress = host + ":" + port;
  64. UAddress address = new UAddress(host, port);
  65. ENetAddress nativeAddress = address.Struct;
  66. this.PeerPtr = NativeMethods.ENetHostConnect(this.poller.Host, ref nativeAddress, 2, 0);
  67. if (this.PeerPtr == IntPtr.Zero)
  68. {
  69. throw new Exception($"host connect call failed, {host}:{port}");
  70. }
  71. this.poller.USocketManager.Add(this.PeerPtr, this);
  72. }
  73. public void SendAsync(byte[] data, byte channelID = 0, PacketFlags flags = PacketFlags.Reliable)
  74. {
  75. if (!isConnected)
  76. {
  77. sendQueue.Enqueue(new BufferInfo { Buffer = data, ChannelID = channelID, Flags = flags });
  78. return;
  79. }
  80. UPacket packet = new UPacket(data, flags);
  81. NativeMethods.ENetPeerSend(this.PeerPtr, channelID, packet.PacketPtr);
  82. // enet_peer_send函数会自动删除packet,设置为0,防止Dispose或者析构函数再次删除
  83. packet.PacketPtr = IntPtr.Zero;
  84. }
  85. internal void OnConnected(ENetEvent eNetEvent)
  86. {
  87. isConnected = true;
  88. while (this.sendQueue.Count > 0)
  89. {
  90. BufferInfo info = this.sendQueue.Dequeue();
  91. this.SendAsync(info.Buffer, info.ChannelID, info.Flags);
  92. }
  93. }
  94. internal void OnReceived(ENetEvent eNetEvent)
  95. {
  96. // 将包放到缓存队列
  97. using (UPacket packet = new UPacket(eNetEvent.Packet))
  98. {
  99. byte[] bytes = packet.Bytes;
  100. this.RecvQueue.Enqueue(bytes);
  101. }
  102. }
  103. internal void OnDisconnect(ENetEvent eNetEvent)
  104. {
  105. Disconnect();
  106. }
  107. }
  108. }