TcpChannel.cs 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Net.Sockets;
  5. using System.Text;
  6. using System.Threading.Tasks;
  7. using Helper;
  8. using Log;
  9. using LoginClient;
  10. namespace LoginClient
  11. {
  12. public class TcpChannel: IMessageChannel
  13. {
  14. private readonly NetworkStream networkStream;
  15. public TcpChannel(TcpClient tcpClient)
  16. {
  17. this.networkStream = tcpClient.GetStream();
  18. }
  19. public void Dispose()
  20. {
  21. this.networkStream.Dispose();
  22. }
  23. public async void SendMessage<T>(ushort opcode, T message, byte channelID = 0)
  24. {
  25. byte[] protoBytes = ProtobufHelper.ToBytes(message);
  26. var neworkBytes = new byte[sizeof(int) + sizeof(ushort) + protoBytes.Length];
  27. int totalSize = sizeof(ushort) + protoBytes.Length;
  28. var totalSizeBytes = BitConverter.GetBytes(totalSize);
  29. totalSizeBytes.CopyTo(neworkBytes, 0);
  30. var opcodeBytes = BitConverter.GetBytes(opcode);
  31. opcodeBytes.CopyTo(neworkBytes, sizeof(int));
  32. protoBytes.CopyTo(neworkBytes, sizeof(int) + sizeof(ushort));
  33. await this.networkStream.WriteAsync(neworkBytes, 0, neworkBytes.Length);
  34. }
  35. public async Task<Tuple<ushort, byte[]>> RecvMessage()
  36. {
  37. int totalReadSize = 0;
  38. int needReadSize = sizeof(int);
  39. var packetBytes = new byte[needReadSize];
  40. while (totalReadSize != needReadSize)
  41. {
  42. int readSize = await this.networkStream.ReadAsync(
  43. packetBytes, totalReadSize, packetBytes.Length);
  44. if (readSize == 0)
  45. {
  46. throw new LoginException("connection closed");
  47. }
  48. totalReadSize += readSize;
  49. }
  50. int packetSize = BitConverter.ToInt32(packetBytes, 0);
  51. Logger.Debug("packetSize: {0}", packetSize);
  52. // 读opcode和message
  53. totalReadSize = 0;
  54. needReadSize = packetSize;
  55. var contentBytes = new byte[needReadSize];
  56. while (totalReadSize != needReadSize)
  57. {
  58. int readSize = await this.networkStream.ReadAsync(
  59. contentBytes, totalReadSize, contentBytes.Length);
  60. if (readSize == 0)
  61. {
  62. throw new LoginException("connection closed");
  63. }
  64. totalReadSize += readSize;
  65. }
  66. ushort opcode = BitConverter.ToUInt16(contentBytes, 0);
  67. var messageBytes = new byte[needReadSize - sizeof(ushort)];
  68. Array.Copy(contentBytes, sizeof(ushort), messageBytes, 0, messageBytes.Length);
  69. return Tuple.Create(opcode, messageBytes);
  70. }
  71. }
  72. }