• socket 降低cpu 占用率 ,放弃Thread和Whell 循环


    1、创建一个消息体的类型

    1. public enum MessageType : byte
    2. {
    3. Unknown = 0,
    4. Chat = 100,
    5. Query = 10,
    6. Identity = 11,
    7. Online = 20,
    8. Offline = 0x25
    9. }

    2、 创建一个消息体(结构包)

    1. public abstract class MessagePackageBase
    2. {
    3. private MessageType a;
    4. protected MessagePackageBase(MessageType type)
    5. {
    6. this.Type = type;
    7. }
    8. internal static MessageType Aa(byte[] A_0)
    9. {
    10. if ((A_0 != null) && (A_0.Length != 0))
    11. {
    12. return (MessageType)A_0[0];
    13. }
    14. return MessageType.Unknown;
    15. }
    16. public virtual byte[] GetPackageData()
    17. {
    18. return new byte[] { (Byte)Type };
    19. }
    20. public MessageType Type
    21. {
    22. get
    23. {
    24. return this.a;
    25. }
    26. set
    27. {
    28. this.a = value;
    29. }
    30. }
    31. }

    3、创建一个处理的包

    1. public class ChatMessagePackage : MessagePackageBase
    2. {
    3. public static readonly Encoding Charset;
    4. private string message;
    5. private DateTime time;
    6. static ChatMessagePackage()
    7. {
    8. Charset = Encoding.Default;
    9. }
    10. public ChatMessagePackage(DateTime time, string message) : base(MessageType.Chat)
    11. {
    12. this.Time = time;
    13. this.Message = message;
    14. }
    15. public static ChatMessagePackage FromPackage(byte[] data)
    16. {
    17. try
    18. {
    19. byte[] destinationArray = new byte[8];
    20. Array.Copy(data, 1, destinationArray, 0, 8);
    21. DateTime time = DateTime.FromBinary(BitConverter.ToInt64(destinationArray, 0));
    22. return new ChatMessagePackage(time, Charset.GetString(data, destinationArray.Length + 1, (data.Length - destinationArray.Length) - 1));
    23. }
    24. catch
    25. {
    26. return null;
    27. }
    28. }
    29. public override byte[] GetPackageData()
    30. {
    31. List<byte> list = new List<byte>(100);
    32. list.AddRange(base.GetPackageData());
    33. list.AddRange(BitConverter.GetBytes(this.Time.ToBinary()));
    34. list.AddRange(Charset.GetBytes(this.Message));
    35. return list.ToArray();
    36. }
    37. public string Message
    38. {
    39. get
    40. {
    41. return message;
    42. }
    43. set
    44. {
    45. message = value;
    46. }
    47. }
    48. public DateTime Time
    49. {
    50. get
    51. {
    52. return time;
    53. }
    54. set
    55. {
    56. time = value;
    57. }
    58. }

    4、创建一个包的事件

    1. public class ChatServerDataReceiveEventArgs : EventArgs
    2. {
    3. private IPEndPoint iP;
    4. private byte[] bytes;
    5. private MessageType type;
    6. public ChatServerDataReceiveEventArgs(IPEndPoint remoteEP, byte[] data)
    7. {
    8. this.RemoteEP = remoteEP;
    9. this.Data = data;
    10. this.MessageType = MessagePackageBase.Aa(data);
    11. }
    12. public IPEndPoint RemoteEP
    13. {
    14. get
    15. {
    16. return iP;
    17. }
    18. set
    19. {
    20. iP = value;
    21. }
    22. }
    23. public byte[] Data
    24. {
    25. get
    26. {
    27. return bytes;
    28. }
    29. set
    30. {
    31. bytes = value;
    32. }
    33. }
    34. public MessageType MessageType
    35. {
    36. get
    37. {
    38. return type;
    39. }
    40. set
    41. {
    42. type = value;
    43. }
    44. }
    45. }

    5、身份包

    1. public class IdentityMessagePackage : MessagePackageBase
    2. {
    3. public IdentityMessagePackage() : base(MessageType.Identity)
    4. {
    5. }
    6. }

    6、离线包

    1. public class OfflineMessagePackage : MessagePackageBase
    2. {
    3. public OfflineMessagePackage() : base(MessageType.Offline)
    4. {
    5. }
    6. }

    7、在线包

    1. public class OnlineMessagePackage : MessagePackageBase
    2. {
    3. public OnlineMessagePackage() : base(MessageType.Online)
    4. {
    5. }
    6. }

    8、查询包

    1. public class QueryMessagePackage : MessagePackageBase
    2. {
    3. public QueryMessagePackage() : base(MessageType.Query)
    4. {
    5. }
    6. }

    9、服务端

    1. public class ChatServer : IDisposable
    2. {
    3. public static int Port;
    4. public static readonly IPAddress BroadcastAddress;
    5. private UdpClient udp;
    6. private bool Run;
    7. private AsyncCallback back;
    8. public event EventHandler DataReceive;
    9. static ChatServer()
    10. {
    11. Port = 2368;
    12. BroadcastAddress = IPAddress.Parse("255.255.255.255");
    13. }
    14. public ChatServer(int port)
    15. {
    16. Port = port;
    17. Run = false;
    18. udp = new UdpClient(Port, AddressFamily.InterNetwork);
    19. back = new AsyncCallback(Result);
    20. }
    21. private void Result(IAsyncResult A_0)
    22. {
    23. if (Run)
    24. {
    25. UdpClient sender = null;
    26. try
    27. {
    28. sender = (UdpClient)A_0.AsyncState;
    29. IPEndPoint remoteEP = new IPEndPoint(IPAddress.Any, 0);
    30. byte[] data = sender.EndReceive(A_0, ref remoteEP);
    31. EventHandler d = this.DataReceive;
    32. if (d != null)
    33. {
    34. d(sender, new ChatServerDataReceiveEventArgs(remoteEP, data));
    35. }
    36. }
    37. catch (ObjectDisposedException)
    38. {
    39. sender = null;
    40. }
    41. catch
    42. {
    43. }
    44. finally
    45. {
    46. if (Run && (sender != null))
    47. {
    48. sender.BeginReceive(back, sender);
    49. }
    50. }
    51. }
    52. }
    53. public void Dispose()
    54. {
    55. this.Stop();
    56. udp = null;
    57. }
    58. public void Start()
    59. {
    60. if (!Run)
    61. {
    62. udp.BeginReceive(back, udp);
    63. Run = true;
    64. }
    65. }
    66. public void Stop()
    67. {
    68. if (Run)
    69. {
    70. Run = false;
    71. udp.Close();
    72. }
    73. }
    74. public void SendMeesage(byte[] datas ,IPEndPoint iPEnd)
    75. {
    76. udp.Send(datas, datas.Length, iPEnd);
    77. }
    78. public void SendPackMesasage(string message, IPEndPoint iPEndPoint)
    79. {
    80. PackMessage(new ChatMessagePackage(DateTime.Now, message), iPEndPoint);
    81. }
    82. private void PackMessage(MessagePackageBase A_0, IPEndPoint point)
    83. {
    84. byte[] packageData = A_0.GetPackageData();
    85. udp.Send(packageData, packageData.Length, point);
    86. }
    87. }

    10 、客户端:

    1. public class ChatClient : IDisposable
    2. {
    3. private UdpClient udp;
    4. public IPEndPoint ServerAddress;
    5. private AsyncCallback back;
    6. static ChatClient()
    7. {
    8. }
    9. public ChatClient()
    10. {
    11. ServerAddress = new IPEndPoint(ChatServer.BroadcastAddress, ChatServer.Port);
    12. udp = new UdpClient();
    13. }
    14. private void PackMessage(MessagePackageBase A_0)
    15. {
    16. byte[] packageData = A_0.GetPackageData();
    17. udp.Send(packageData, packageData.Length, ServerAddress);
    18. }
    19. public void Dispose()
    20. {
    21. udp.Close();
    22. udp = null;
    23. }
    24. public void Offline()
    25. {
    26. PackMessage(new OfflineMessagePackage());
    27. }
    28. public void Online()
    29. {
    30. PackMessage(new OnlineMessagePackage());
    31. }
    32. public void Query()
    33. {
    34. PackMessage(new QueryMessagePackage());
    35. }
    36. public void SendIdentity()
    37. {
    38. PackMessage(new IdentityMessagePackage());
    39. }
    40. public void SendPackMessage(string message)
    41. {
    42. PackMessage(new ChatMessagePackage(DateTime.Now, message));
    43. }
    44. public void SendMessage(byte[] datas)
    45. {
    46. udp.Send(datas, datas.Length, ServerAddress);
    47. }
    48. }

    11、调用

    1. private ChatServer ChatServer;
    2. void StartInit()
    3. {
    4. ChatServer = new ChatServer(ContentConfig.Load().NetWorkControl.Port);
    5. ChatServer.DataReceive += new EventHandler(Chatserver_DataReceive);
    6. ChatServer.Start();
    7. }
    8. //JIESHOU
    9. private void Chatserver_DataReceive(object sender, ChatServerDataReceiveEventArgs e)
    10. {
    11. if (e.Data != null)
    12. {
    13. byte[] data = e.Data;
    14. //TODO......
    15. }
    16. }

  • 相关阅读:
    【Qt常用控件】—— QWidget 核心属性
    【AI视野·今日NLP 自然语言处理论文速览 第四十四期】Fri, 29 Sep 2023
    汽车数字化转型:存储驱动创新未来
    kubebuilder的安装与基本使用
    MySQL事务原理之MVCC和锁机制
    基础会计学原理重点整理(精编!!)
    聊聊并发编程——并发容器和阻塞队列
    移动硬盘删除的文件如何恢复呢?
    【LeetCode-中等】238. 除自身以外数组的乘积(详解)
    我记不住的那些命令(不断更新中)
  • 原文地址:https://blog.csdn.net/weixin_38826167/article/details/127824551