.NET Mailslot通信实现

在分布式系统中,服务器与客户端之间的通信是一个常见的需求。Mailslot是一种特殊的通信机制,允许多个客户端向服务器发送消息,而无需服务器确认。这种“fire-and-forget”的通信方式在某些场景下非常有用,例如日志记录、通知等。然而,.NET标准库并没有提供直接支持Mailslot操作的类,现有的一些封装也不够简洁和优雅。因此,本文将介绍一种自定义的Mailslot实现方式。

服务器端实现

服务器端的实现涉及到创建一个Mailslot,并监听来自客户端的消息。以下是服务器端的代码示例:

using System; using System.IO; using System.Runtime.InteropServices; using System.Text; using System.Threading; public class MailslotServer : IDisposable { private SafeMailslotHandle _handle; public MailslotServer(string name) { _handle = CreateMailslot($"\\\\.\\mailslot\\{name}", 0, 0, IntPtr.Zero); if (_handle.IsInvalid) throw new Win32Exception(); } public string GetNextMessage() { int messageBytes; int bytesRead; int messages; if (!GetMailslotInfo(_handle, IntPtr.Zero, out messageBytes, out messages, IntPtr.Zero)) throw new Win32Exception(); if (messageBytes == Mailslot.MailslotNoMessage) return null; var bBuffer = new byte[messageBytes]; if (!ReadFile(_handle, bBuffer, messageBytes, out bytesRead, IntPtr.Zero) || bytesRead == 0) throw new Win32Exception(); return Encoding.Unicode.GetString(bBuffer); } public void Dispose() { if (_handle != null) { _handle.Close(); _handle = null; } } }

服务器端首先创建一个Mailslot,然后通过调用GetNextMessage方法来获取客户端发送的消息。如果Mailslot中没有消息,则返回null。

客户端实现

客户端的实现相对简单,只需要向服务器端创建的Mailslot发送消息即可。以下是客户端的代码示例:

public class MailslotClient : IDisposable { private SafeMailslotHandle _handle; private readonly string _name; private readonly string _machine; public MailslotClient(string name) : this(name, ".") { } public MailslotClient(string name, string machine) { _name = name; _machine = machine; } public void SendMessage(string msg) { if (_handle == null) CreateHandle(); int bytesWritten; byte[] bMessage = Encoding.Unicode.GetBytes(msg); bool succeeded = WriteFile(_handle, bMessage, bMessage.Length, out bytesWritten, IntPtr.Zero); if (!succeeded || bMessage.Length != bytesWritten) { if (_handle != null) _handle.Close(); _handle = null; throw new Win32Exception(); } } public void Dispose() { if (_handle != null) { _handle.Close(); _handle = null; } } private void CreateHandle() { _handle = CreateFile($"\\\\{_machine}\\mailslot\\{_name}", FileDesiredAccess.GenericWrite, FileShareMode.FileShareRead, IntPtr.Zero, FileCreationDisposition.OpenExisting, 0, IntPtr.Zero); if (_handle.IsInvalid) throw new Win32Exception(); } }
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485