问题描述
从Windows Insider内部版本17093(Windows 10版本1803)开始,Windows上支持
AF_UNIX套接字。 请参阅Windows命令行博客上的Windows/WSL Interop with AF_UNIX博客文章。 可以使用它与两个.NET Core应用程序(客户端和服务器)进行Windows / WSL互操作 谢谢
解决方法
您需要 UnixDomainSocketEndPoint 类。
另请注意,这仅适用于 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[2];
_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,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);
}
}
}
}