在 windows 上是否有 AF_UNIX 支持 Windows/WSL Interop on .NET Core

Is there an AF_UNIX support on windows for Windows/WSL Interop on .NET Core

从 Windows Insider build 17093(Windows 10 版本 1803)开始,Windows 支持

AF_UNIX 套接字。 请参阅 Windows 命令行博客上的 Windows/WSL Interop with AF_UNIX 博客 post。 有任何方法可以使用它 Windows/WSL 与两个 .NET Core 应用程序(客户端和服务器)互操作 谢谢

您需要 UnixDomainSocketEndPoint class.

另请注意,这仅适用于 WSL 版本 1,不适用于版本 2。

这是我刚刚拼凑的一个快速工作示例。请注意,没有真正的错误处理或强大的输入验证。

您需要在命令行提供路径,创建 c:\tmp\wsl 目录,或在代码中编辑路径。

using System;
using System.IO;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Text;

namespace AFUnixTest
{
    class Program
    {
        static UnixDomainSocketEndPoint _endpoint;
        static Socket UnixSocket => new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.Unspecified);
        static bool IsLinux => RuntimeInformation.IsOSPlatform(OSPlatform.Linux);
        static string _socketPath;
        static byte[] _buffer = new byte[1024];

        static void Main(string[] args)
        {
            _socketPath = IsLinux ? "/mnt/c/tmp/wsl/unix.sock" : "c:\tmp\wsl\unix.sock";
            if (args.Length == 0)
            {
                Usage();
                return;
            }
            if (args.Length > 1) _socketPath = args[1];
            _endpoint = new UnixDomainSocketEndPoint(_socketPath);
            if (args[0].ToLower() == "-s")
            {
                Server();
            }
            else if (args[0].ToLower() == "-c")
            {
                Client();
            }
            else
            {
                Usage();
            }
        }

        static void Usage()
        {
            Console.WriteLine("Usage:");
            Console.WriteLine($"  { AppDomain.CurrentDomain.FriendlyName } -s or -c [socket path]");
            Console.WriteLine($"    Socket path should be in { (IsLinux ? "Linux" : "Windows") } path format.");
        }

        static void Server()
        {
            if (File.Exists(_socketPath)) File.Delete(_socketPath);
            Console.WriteLine("Waiting...");
            using (Socket listener = UnixSocket)
            {
                listener.Bind(_endpoint);
                listener.Listen(10);
                using (Socket handler = listener.Accept())
                {
                    while (true)
                    {
                        int bytesReceived = handler.Receive(_buffer);
                        string message = Encoding.ASCII.GetString(_buffer, 0, bytesReceived);
                        if (message.ToLower().StartsWith("exit")) break;
                        Console.WriteLine($"Received [{ message }].");
                    }
                    Console.WriteLine("Exit received. Exiting...");
                    handler.Shutdown(SocketShutdown.Both);
                }
            }
        }

        static void Client()
        {
            Console.WriteLine("Starting client. Enter text. \"Exit\" (without quotes) to quit.");
            using (Socket sender = UnixSocket)
            {
                sender.Connect(_endpoint);
                while (true)
                {
                    string message = Console.ReadLine();
                    var output = Encoding.ASCII.GetBytes(message);
                    int bytesSent = sender.Send(output);
                    Console.WriteLine($"Sent [{ bytesSent }] bytes.");
                    if (message.ToLower().StartsWith("exit")) break;
                }
                sender.Shutdown(SocketShutdown.Both);
            }
        }
    }
}