KcpClient.cs 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. using System;
  2. namespace IFramework.Net.KCP
  3. {
  4. public class KcpClient
  5. {
  6. private Kcp _kcp = null;
  7. private BufferQueue _buffer;
  8. private UInt32 _time = 0;
  9. public IKcpSocket socket;
  10. private ISessionListener _listen;
  11. public bool writeDelay;
  12. public bool ackNoDelay;
  13. public KcpClient(IKcpSocket client, ISessionListener listen)
  14. {
  15. _buffer = BufferQueue.Allocate(1024 * 32);
  16. this.socket = client;
  17. this._listen = listen;
  18. client.onMessage += Socket_onMessage;
  19. }
  20. private void Socket_onMessage(byte[] buffer, int offset, int length)
  21. {
  22. var inputN = _kcp.Input(buffer, offset, length, true, ackNoDelay);
  23. if (inputN < 0) return;
  24. _buffer.Clear();
  25. while (true)
  26. {
  27. var size = _kcp.PeekSize();
  28. if (size <= 0) break;
  29. _buffer.EnsureWritableBytes(size);
  30. var n = _kcp.Recv(_buffer.buffer, _buffer.writer, size);
  31. if (n > 0) _buffer.writer += n;
  32. }
  33. // 有数据待接收
  34. if (_buffer.canRead > 0)
  35. {
  36. _listen.OnMessage(socket,_buffer.buffer, _buffer.reader, _buffer.canRead);
  37. // 读完重置读写指针
  38. if (_buffer.reader == _buffer.writer)
  39. {
  40. _buffer.Clear();
  41. }
  42. }
  43. }
  44. public void Connect(string host, int port)
  45. {
  46. _kcp = new Kcp((uint)(new Random().Next(1, Int32.MaxValue)), socket);
  47. _kcp.NoDelay(0, 30, 2, true);
  48. _kcp.stream = true;
  49. _buffer.Clear();
  50. socket.Connect(host,port);
  51. }
  52. public int Send(byte[] data, int index, int length)
  53. {
  54. var waitsnd = _kcp.waitToSend;
  55. if (waitsnd < _kcp.sendWindow && waitsnd < _kcp.RmtWnd)
  56. {
  57. var sendBytes = 0;
  58. do
  59. {
  60. var n = Math.Min((int)_kcp.Mss, length - sendBytes);
  61. _kcp.Send(data, index + sendBytes, n);
  62. sendBytes += n;
  63. } while (sendBytes < length);
  64. waitsnd = _kcp.waitToSend;
  65. if (waitsnd >= _kcp.sendWindow || waitsnd >= _kcp.RmtWnd || !writeDelay)
  66. {
  67. _kcp.Flush(false);
  68. }
  69. return length;
  70. }
  71. return 0;
  72. }
  73. public void Close()
  74. {
  75. _buffer.Clear();
  76. socket.Close();
  77. }
  78. public void Update()
  79. {
  80. if (0 == _time || _kcp.time >= _time)
  81. {
  82. _kcp.Update();
  83. _time = _kcp.Check();
  84. }
  85. }
  86. }
  87. }