Я хочу написать простое приложение, которое обменивается данными между хостом Hyper-V и его виртуальной машиной с помощью сокетов Hyper-V (netcat over vsock). В Inte rnet есть несколько документов, описывающих, как это сделать: Создайте свои собственные службы интеграции , Практическая связь через сокет Hyper-V . Однако любой из них помогает мне достичь своей цели.
Прежде всего, я убедился, что соединение с использованием сокетов Hyper-V возможно. На гостевом Linux я загрузил hv_sock
модуль и запустил n c -vsock приложение, которое может прослушивать vsocks:
$ sudo modprobe hv_sock
$ nc-vsock -l 1234
Вкл Windows в PowerShell Я запустил hv c, который использует сокеты Hyper-V и способен эмулировать netcat:
hvc nc -t vsock little-helper 1234
, и это работает. Я могу видеть данные, отправленные с сервера клиенту и наоборот.
Затем я написал простое приложение, основанное на 1 и 2 с небольшими изменениями. Я зарегистрировал свое приложение в реестре хоста Hyper-V, как указано в 1 , и запустил свое приложение. Соединение не было установлено, и функция connect
вернула ошибку 10049.
Я пытался запустить свое приложение от имени администратора и манипулировать GUID в исходном коде, а также в реестре хоста Hyper-V. Однако ничего не помогает и приложение всегда сообщает об ошибке 10049.
На мой взгляд в документе есть некоторая двусмысленность. Например, сказано, что идентификатор сервиса должен быть случайным GUID. Но позже есть примечание, что первые четыре октета преобразуются в порт в семействе адресов AF_VSOCK, и для этой цели предоставляется специфицированный c GUID.
Вопрос довольно прост: что я сделал неправильно или неправильно понял , Можно ли написать netcat, используя vsock между Windows и Linux?
Полный код:
#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;
}