根据 vSockets API 文档,它说:
“最初的 VMCI 库是作为 Workstation 6.0 的实验性 C 语言接口发布的。VMCI 包括一个数据报 API 和一个共享内存 API。这两个接口在 Workstation 6.5 中都已停用。”
所以现在看来您只能使用 vmci SOCK_DGRAM 或 SOCK_STREAM 套接字。它们的行为很像 tcp/ip 套接字,网上有很多关于如何编写使用它们的代码的信息,你基本上只需要头文件 vmci_sockets.h 就可以了。
您会发现 vsocket 通信的来宾端简单明了,但是您需要编写某种服务器以在 ESXi 主机上运行来托管您的数据库,这是棘手的部分。如果您在 ESXi 上启用 ssh 并进行嗅探,您会发现一个非常类似于 unix 的系统,其中包含 /dev/vsock 设备,您可以查询该设备以获取 vsocket 协议系列(对于您的客人可能会有所不同,您需要调用ioctl)。不幸的是(我试过了)简单地编译一个 64 位静态链接的 Linux 二进制文件只会给你带来段错误,因为 ESXi 操作系统与 Linux 不够相似。
有一个 SDK,您可以尝试使用它来创建程序,但它不适合胆小的人,有些人已经花了几天时间试图让它编译,所以如果您愿意,您可以尝试这条路线,但我不推荐它。谷歌搜索“VMWare ESXi 工具链”。
但是,如果您正在寻找更快的途径让自己的服务器在 ESXi 上运行,并且准备使用 Python,您会发现 5.5 和 6.0 都带有相当最新的 Python(Python 2.7. 9 在 ESXi v6.0 上)。 VMWare 毫无帮助地删除了 .py 库文件,只留下了 .pyc 文件,因此您无法轻易看出这是否与标准版本不同,但它的功能肯定足以让基本的套接字服务器运行。
Python 套接字模块不了解 vmci 套接字系列,因此您需要使用 ctypes 绕过它,直接调用 c 库套接字函数。您可以使用纯 python 创建套接字,甚至调用 listen() 但例如bind() 隐含地希望您处理 sockaddr_in 结构。
因此,您需要检查 vmci_sockets.h 标头,并提出 Python ctypes 结构和函数来镜像您从 C 中使用的结构和函数,例如:
class sockaddr_vm(Structure):
_fields_ = [("svm_family", c_ushort),
("svm_reserved1", c_ushort),
("svm_port", c_uint),
("svm_cid", c_uint),
("svm_zero", c_uint),
]
然后可以将其传递到您可以访问的 libc bind/recvfrom/sendto 调用中:
libc = cdll.LoadLibrary("libc.so.6")
然后您可以绕过 Python 套接字模块绑定到您的套接字,即
addr = sockaddr_vm()
addr.svm_family = af # address family obtained from ioctl
addr.svm_reserved1 = 0
addr.svm_cid = VMADDR_CID_ANY # 0xffffffff
addr.svm_port = port
addr.svm_zero = 0
# s is the socket, created with python socket.socket()
out = libc.bind(s.fileno(), pointer(addr), sizeof(addr))
在 ESXi 上使用 Python 的一个警告是,您可以使用的内存似乎有限:我尝试分配一个 16MB 的缓冲区,但 Python 拒绝给我它并出现内存错误,但这不是问题我当时在做什么,所以我没有费心去想办法解决它。我怀疑有一个设置可以解决这个问题。
在 ESXi 引导时启动脚本留给读者作为练习,但这应该可以帮助您入门。玩得开心!