【发布时间】:2020-06-26 23:40:54
【问题描述】:
我想编写一个简单的应用程序,使用 Hyper-V 套接字(netcat over vsock)在 Hyper-V 主机与其虚拟机之间进行通信。在 Internet 上有一些文档描述了如何做到这一点:Make your own integration services、Practical Hyper-V socket communication。但是,它们中的任何一个都可以帮助我实现目标。
首先,我确保可以使用 Hyper-V 套接字进行连接。在来宾 Linux 上,我加载了 hv_sock 模块并运行 nc-vsock 应用程序,它能够监听 vsocks:
$ sudo modprobe hv_sock
$ nc-vsock -l 1234
在 PowerShell 中的 Windows 上,我运行了 hvc,它利用 Hyper-V 套接字并能够模拟 netcat:
hvc nc -t vsock little-helper 1234
它有效。我可以看到从服务器发送到客户端的数据,反之亦然。
然后我基于1 和2 编写了一个简单的应用程序,稍作改动。
如1 所述,我在 Hyper-V 主机的注册表中注册了我的应用程序,然后运行了我的应用程序。连接未建立,connect 函数返回错误 10049。
我尝试以管理员身份运行我的应用程序,并在源代码和 Hyper-V 主机的注册表中操作 GUID。但是,没有任何帮助,应用程序总是报告错误 10049。
在我看来,文档中有些含糊不清。例如。据说服务ID应该是一个随机的GUID。但后来有一个说明,前四个八位字节转换为 AF_VSOCK 地址族中的端口,并为此提供了特定的 GUID。
问题很简单:我做错了什么或误解了什么。是否可以在 Windows 和 Linux 之间使用 vsock 编写 netcat?
完整代码:
#include <iostream>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <hvsocket.h>
#include <combaseapi.h>
int main()
{
struct __declspec(uuid("00000000-185c-4e04-985a-4c2eee3e03cc")) VSockTemplate {};
struct __declspec(uuid("2a9fa68e-4add-45cb-85c8-de97fc66d388")) ServerVsockTemplate {};
//----------------------
// Initialize Winsock
WSADATA wsaData;
int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != NO_ERROR) {
wprintf(L"WSAStartup function failed with error: %d\n", iResult);
return 1;
}
//----------------------
// Create a SOCKET for connecting to server
SOCKET ConnectSocket;
ConnectSocket = socket(AF_HYPERV, SOCK_STREAM, HV_PROTOCOL_RAW);
if (ConnectSocket == INVALID_SOCKET) {
wprintf(L"socket function failed with error: %ld\n", WSAGetLastError());
WSACleanup();
return 1;
}
//----------------------
// The sockaddr_in structure specifies the address family,
// IP address, and port of the server to be connected to.
SOCKADDR_HV clientService;
clientService.Family = AF_HYPERV;
clientService.VmId = __uuidof(ServerVsockTemplate);
clientService.ServiceId = __uuidof(VSockTemplate);
clientService.ServiceId.Data1 = 1234;
//----------------------
// Connect to server.
iResult = connect(ConnectSocket, (SOCKADDR*)&clientService, sizeof(clientService));
if (iResult == SOCKET_ERROR) {
wprintf(L"connect function failed with error: %ld\n", WSAGetLastError());
iResult = closesocket(ConnectSocket);
if (iResult == SOCKET_ERROR)
wprintf(L"closesocket function failed with error: %ld\n", WSAGetLastError());
WSACleanup();
return 1;
}
wprintf(L"Connected to server.\n");
iResult = closesocket(ConnectSocket);
if (iResult == SOCKET_ERROR) {
wprintf(L"closesocket function failed with error: %ld\n", WSAGetLastError());
WSACleanup();
return 1;
}
WSACleanup();
return 0;
}
【问题讨论】:
标签: linux windows sockets hyper-v