gpt4 book ai didi

c# - MSYS/Cygwin 使用什么机制来模拟 Unix 域套接字?

转载 作者:可可西里 更新时间:2023-11-01 09:08:56 25 4
gpt4 key购买 nike

我正在尝试编写(在 C# 中)一个软件,该软件通过(MSYS 模拟的)Unix 域套接字与另一个使用 MSYS 构建的软件进行通信。我了解到“套接字服务器”(我不清楚正确的术语是什么)会创建一个临时文件,其内容如下:

!<socket >59108 282F93E1-9E2D051A-46B57EFC-64A1852F

59108 对应于一个 TCP 端口,“套接字服务器”正在环回接口(interface)上监听该端口。使用数据包捕获工具,我已经能够确定“套接字客户端”连接到此端口,并通过环回接口(interface)交换信息。

我在我的软件中复制了这个行为,“套接字客户端”连接到我的监听端口,但没有传输任何信息。我相信这里还有另一个步骤,最有可能涉及“套接字”文件中的 GUID,但我一直无法确定它是什么。我需要做什么来触发客户端的通信?

似乎 MSYS 正在使用 Cygwin 的机制,该机制涉及一个命名事件,该事件(可能?)由“服务器”创建,并(显然)由“服务器”发出信号,但我天真的实现尝试并没有' 似乎在工作。

我找到了 an email written by Conrad Scott它描述了“握手”过程中的各种缺点,并提出了据称可以解决这些问题的补丁。在这封电子邮件中,康拉德描述了一些使用的过程,他指出实际上有两个事件,一个由“服务器”管理,一个由“客户端”管理。我用过 API Monitor查找对 CreateEvent() 的调用,尽管有多个调用,但我在这里找不到看起来像“确凿证据”的调用。也没有对 CreateSemaphore() 的有趣调用,因此似乎从未应用 Conrad 的补丁(或者至少在 MSYS fork Cygwin 之后的某个时间应用了它)。

最佳答案

看起来 divB 和 Mark 的答案都是正确的,但他们都遗漏了一些细节,所以希望这更完整一些。

这里有两种不同的实现方式。我没有详尽调查谁实现了哪个实现,但截至撰写本文时,当前版本的 cygwin 使用 divB 描述的实现,而 MsysGit 使用 Mark 描述的实现。

初始化服务器:

  1. 创建一个套接字(AddressFamily = IPv4,Type = Stream,Protocol = TCP)。 ( .NET/MFC )
  2. 将其绑定(bind)到环回 (127.0.0.1)。 ( .NET/MFC )
  3. 告诉套接字听。 ( .NET/MFC )
  4. 生成一个随机的 16 字节 GUID。
  5. 根据 TCP 端口和 GUID 创建包含以下内容的文件。使用原始示例,其中 59108 是 TCP 端口,282F93E1-9E2D051A-46B57EFC-64A1852F 是 GUID。

    在cygwin实现中,socket文件内容为:

    !<socket >59108 s 282F93E1-9E2D051A-46B57EFC-64A1852F

    而在msysgit实现中,socket文件内容为:

    !<socket >59108 282F93E1-9E2D051A-46B57EFC-64A1852F

    区别在于端口和 GUID 之间的额外“s”。

  6. 在此文件上设置系统属性。

  7. 仅在 msysgit 实现中,创建一个名为 cygwin.local_socket.secret.58598.282F93E1-9E2D051A-46B57EFC-64A1852F 的命名等待句柄(InitalState = False,Reset = AutoReset)。 ( .NET/MFC )

    58598 是通过在端口上使用 HostToNetworkOrder 函数派生的(作为 16 位无符号整数)。即 59108 == 0xE6E4 和 58598 == 0xE4E6。

处理连接:

  1. 接受传入的套接字。 ( .NET/MFC )。
  2. 仅在 cygwin 实现的情况下,执行包含以下内容的握手:
    1. 读取 16 个字节。如果这些与 GUID 不匹配,则失败。
    2. 发送相同的 16 个字节。
    3. 将 12 个字节读取为 3 个 32 位整数。它们是调用进程的pid、uid和gid。
    4. 发回 12 个字节(3 个 32 位整数)。使用服务器的 pid 以及收到的 uid 和 gid。
  3. 仅在 msysgit 实现的情况下,通过以下方式与客户端同步:
    1. 获取传入套接字的端口。对于此示例,我们将其设为 63524
    2. 为客户端打开现有的等待句柄。 ( .NET/MFC )。您需要将端口转换为网络字节顺序,就像我们为服务器所做的那样。因此,对于此示例,名称为 cygwin.local_socket.secret.9464.282F93E1-9E2D051A-46B57EFC-64A1852F
    3. 向服务器发送信号并等待客户端(ToSignal = 服务器,WaitOn = 客户端,超时 = 10000 毫秒,ExitContext/Alertable = False)。 ( .NET/MFC )。不能 100% 确定 ExitContext/Alertable 参数,但 False 似乎有效。
  4. 无论您在做什么,都将套接字交给(希望已经存在的)代码(在我们三个人的情况下,这似乎是一个 ssh 代理)。

关于c# - MSYS/Cygwin 使用什么机制来模拟 Unix 域套接字?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23086038/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com