feat: Рабочая версия клиента
This commit is contained in:
parent
9d71f33432
commit
53cc2a08ce
4 changed files with 74 additions and 65 deletions
|
@ -12,7 +12,7 @@ endif()
|
||||||
project ("shell-server")
|
project ("shell-server")
|
||||||
|
|
||||||
# Добавьте источник в исполняемый файл этого проекта.
|
# Добавьте источник в исполняемый файл этого проекта.
|
||||||
add_executable (shell-server "main.c" "server.c" "server.h")
|
add_executable (shell-server "main.c" "server.c" "server.h" "client.c" "client.h")
|
||||||
|
|
||||||
if (CMAKE_VERSION VERSION_GREATER 3.12)
|
if (CMAKE_VERSION VERSION_GREATER 3.12)
|
||||||
set_property(TARGET shell-server PROPERTY CXX_STANDARD 20)
|
set_property(TARGET shell-server PROPERTY CXX_STANDARD 20)
|
||||||
|
|
17
main.c
17
main.c
|
@ -3,14 +3,9 @@
|
||||||
|
|
||||||
#include "server.h"
|
#include "server.h"
|
||||||
|
|
||||||
int _tmain(int argc, TCHAR *argv[]) {
|
int _tmain(int argc, char *argv[]) {
|
||||||
if (argc == 2) {
|
if (argc == 2) {
|
||||||
// TODO: implement client
|
if (lstrcmpi(argv[1], TEXT("-s")) == 0) {
|
||||||
if (lstrcmpi(argv[1], TEXT("-c")) == 0) {
|
|
||||||
// StartShellClient();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else if (lstrcmpi(argv[1], TEXT("-s")) == 0) {
|
|
||||||
StartShellServer();
|
StartShellServer();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -20,8 +15,12 @@ int _tmain(int argc, TCHAR *argv[]) {
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (argc == 3) {
|
else if (argc == 3) {
|
||||||
|
if (lstrcmpi(argv[1], TEXT("-c")) == 0) {
|
||||||
|
StartShellClient(argv[2]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
// TODO: implement service
|
// TODO: implement service
|
||||||
if (lstrcmpi(argv[1], TEXT("-s")) == 0 && lstrcmpi(argv[2], TEXT("-service")) == 0) {
|
else if (lstrcmpi(argv[1], TEXT("-s")) == 0 && lstrcmpi(argv[2], TEXT("-service")) == 0) {
|
||||||
// CreateService
|
// CreateService
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -35,7 +34,7 @@ int _tmain(int argc, TCHAR *argv[]) {
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
help_message:
|
help_message:
|
||||||
printf("Wrong usage\nUsage: %s [-c | -s [-service]]\n", argv[0]);
|
printf("Wrong usage\nUsage: %s [-c {remote ip} | -s [-service]]\n", argv[0]);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
110
server.c
110
server.c
|
@ -1,7 +1,6 @@
|
||||||
#include "server.h"
|
#include "server.h"
|
||||||
|
|
||||||
#define BUFSIZE 4096
|
#define BUFSIZE 4096
|
||||||
#define DEFAULT_PORT "50113"
|
|
||||||
#define DEFAULT_BUFLEN 512
|
#define DEFAULT_BUFLEN 512
|
||||||
|
|
||||||
typedef struct PipeThreadInfo_t {
|
typedef struct PipeThreadInfo_t {
|
||||||
|
@ -10,6 +9,7 @@ typedef struct PipeThreadInfo_t {
|
||||||
} PipeThreadInfo;
|
} PipeThreadInfo;
|
||||||
|
|
||||||
void CreateChildProcess(HANDLE g_hChildStd_IN_Rd, HANDLE g_hChildStd_OUT_Wr);
|
void CreateChildProcess(HANDLE g_hChildStd_IN_Rd, HANDLE g_hChildStd_OUT_Wr);
|
||||||
|
DWORD WINAPI WorkWithClient(LPVOID lpParam);
|
||||||
DWORD WINAPI WriteToPipe(LPVOID lpParam);
|
DWORD WINAPI WriteToPipe(LPVOID lpParam);
|
||||||
DWORD WINAPI ReadFromPipe(LPVOID lpParam);
|
DWORD WINAPI ReadFromPipe(LPVOID lpParam);
|
||||||
void ErrorExit(PCTSTR);
|
void ErrorExit(PCTSTR);
|
||||||
|
@ -17,29 +17,15 @@ void ErrorExit(PCTSTR);
|
||||||
void StartShellServer() {
|
void StartShellServer() {
|
||||||
printf("\n->Start of shell server execution.\n");
|
printf("\n->Start of shell server execution.\n");
|
||||||
|
|
||||||
/*
|
|
||||||
* Server variables
|
|
||||||
*/
|
|
||||||
WSADATA wsaData;
|
WSADATA wsaData;
|
||||||
struct addrinfo* result = NULL, * ptr = NULL, hints;
|
struct addrinfo* result = NULL, * ptr = NULL, hints;
|
||||||
SOCKET ListenSocket = INVALID_SOCKET;
|
|
||||||
int iResult;
|
int iResult;
|
||||||
|
|
||||||
/*
|
|
||||||
* Client variables
|
|
||||||
*/
|
|
||||||
SOCKET ClientSocket = INVALID_SOCKET;
|
SOCKET ClientSocket = INVALID_SOCKET;
|
||||||
// Pipe handles for child STDIN/STDOUT
|
SOCKET ListenSocket = INVALID_SOCKET;
|
||||||
HANDLE g_hChildStd_IN_Rd = NULL;
|
|
||||||
HANDLE g_hChildStd_IN_Wr = NULL;
|
|
||||||
HANDLE g_hChildStd_OUT_Rd = NULL;
|
|
||||||
HANDLE g_hChildStd_OUT_Wr = NULL;
|
|
||||||
|
|
||||||
SECURITY_ATTRIBUTES saAttr;
|
/*
|
||||||
HANDLE PipeThreads[2];
|
* Initialize listening socket
|
||||||
|
|
||||||
/*
|
|
||||||
* Initialize listening socket
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Initialize Winsock
|
// Initialize Winsock
|
||||||
|
@ -94,6 +80,46 @@ void StartShellServer() {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Process client connection
|
||||||
|
*/
|
||||||
|
for (;;) {
|
||||||
|
// Accepting a client connection
|
||||||
|
ClientSocket = INVALID_SOCKET;
|
||||||
|
|
||||||
|
ClientSocket = accept(ListenSocket, NULL, NULL);
|
||||||
|
if (ClientSocket == INVALID_SOCKET) {
|
||||||
|
printf("accept failed: %d\n", WSAGetLastError());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
printf("Client connected\n");
|
||||||
|
// Create separate thread to process client connection
|
||||||
|
CreateThread(NULL, 0, WorkWithClient, ClientSocket, 0, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Finalization
|
||||||
|
*/
|
||||||
|
// TODO: properly close all handles
|
||||||
|
closesocket(ListenSocket);
|
||||||
|
WSACleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD WINAPI WorkWithClient(LPVOID lpParam) {
|
||||||
|
/*
|
||||||
|
* Client variables
|
||||||
|
*/
|
||||||
|
// Pipe handles for child STDIN/STDOUT
|
||||||
|
HANDLE g_hChildStd_IN_Rd = NULL;
|
||||||
|
HANDLE g_hChildStd_IN_Wr = NULL;
|
||||||
|
HANDLE g_hChildStd_OUT_Rd = NULL;
|
||||||
|
HANDLE g_hChildStd_OUT_Wr = NULL;
|
||||||
|
|
||||||
|
SECURITY_ATTRIBUTES saAttr;
|
||||||
|
HANDLE PipeThreads[2];
|
||||||
|
|
||||||
|
SOCKET ClientSocket = (SOCKET)lpParam;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize pipes
|
* Initialize pipes
|
||||||
*/
|
*/
|
||||||
|
@ -119,26 +145,11 @@ void StartShellServer() {
|
||||||
ErrorExit(TEXT("Stdin SetHandleInformation"));
|
ErrorExit(TEXT("Stdin SetHandleInformation"));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create child process
|
* Create child process cmd.exe
|
||||||
*/
|
*/
|
||||||
CreateChildProcess(g_hChildStd_IN_Rd, g_hChildStd_OUT_Wr);
|
CreateChildProcess(g_hChildStd_IN_Rd, g_hChildStd_OUT_Wr);
|
||||||
|
|
||||||
/*
|
|
||||||
* Process client connection
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Accepting a connection
|
|
||||||
ClientSocket = INVALID_SOCKET;
|
|
||||||
|
|
||||||
// Accept a client socket
|
|
||||||
ClientSocket = accept(ListenSocket, NULL, NULL);
|
|
||||||
if (ClientSocket == INVALID_SOCKET) {
|
|
||||||
printf("accept failed: %d\n", WSAGetLastError());
|
|
||||||
closesocket(ListenSocket);
|
|
||||||
WSACleanup();
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// Create threads for STDIN/STDOUT
|
||||||
PipeThreadInfo WriteThreadInfo = { g_hChildStd_IN_Wr, ClientSocket };
|
PipeThreadInfo WriteThreadInfo = { g_hChildStd_IN_Wr, ClientSocket };
|
||||||
PipeThreadInfo ReadThreadInfo = { g_hChildStd_OUT_Rd, ClientSocket };
|
PipeThreadInfo ReadThreadInfo = { g_hChildStd_OUT_Rd, ClientSocket };
|
||||||
PipeThreads[0] = CreateThread(NULL, 0, WriteToPipe, &WriteThreadInfo, 0, NULL);
|
PipeThreads[0] = CreateThread(NULL, 0, WriteToPipe, &WriteThreadInfo, 0, NULL);
|
||||||
|
@ -147,12 +158,6 @@ void StartShellServer() {
|
||||||
WaitForMultipleObjects(2, PipeThreads, TRUE, INFINITE);
|
WaitForMultipleObjects(2, PipeThreads, TRUE, INFINITE);
|
||||||
|
|
||||||
printf("\n->Client disconnected.\n");
|
printf("\n->Client disconnected.\n");
|
||||||
|
|
||||||
/*
|
|
||||||
* Finalization
|
|
||||||
*/
|
|
||||||
// TODO: properly close all handles
|
|
||||||
closesocket(ListenSocket);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CreateChildProcess(HANDLE g_hChildStd_IN_Rd, HANDLE g_hChildStd_OUT_Wr)
|
void CreateChildProcess(HANDLE g_hChildStd_IN_Rd, HANDLE g_hChildStd_OUT_Wr)
|
||||||
|
@ -222,13 +227,19 @@ DWORD WINAPI WriteToPipe(LPVOID lpParam)
|
||||||
char recvbuf[DEFAULT_BUFLEN];
|
char recvbuf[DEFAULT_BUFLEN];
|
||||||
int iResult, iSendResult;
|
int iResult, iSendResult;
|
||||||
int recvbuflen = DEFAULT_BUFLEN;
|
int recvbuflen = DEFAULT_BUFLEN;
|
||||||
|
|
||||||
|
// Change codepage to UTF-8
|
||||||
|
//CHAR chcpCommand[] = "chcp 65001\n";
|
||||||
|
//bSuccess = WriteFile(g_hChildStd_IN_Wr, chcpCommand, strlen(chcpCommand), &dwWritten, NULL);
|
||||||
|
//if (!bSuccess) goto WriteToPipe_end;
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
iResult = recv(ClientSocket, recvbuf, recvbuflen, 0);
|
iResult = recv(ClientSocket, recvbuf, recvbuflen, 0);
|
||||||
if (iResult > 0) {
|
if (iResult > 0) {
|
||||||
bSuccess = WriteFile(g_hChildStd_IN_Wr, recvbuf, iResult, &dwWritten, NULL);
|
bSuccess = WriteFile(g_hChildStd_IN_Wr, recvbuf, iResult, &dwWritten, NULL);
|
||||||
if (!bSuccess) break;
|
if (!bSuccess) break;
|
||||||
|
printf("Received command: %s\n");
|
||||||
}
|
}
|
||||||
else if (iResult == 0)
|
else if (iResult == 0)
|
||||||
printf("Connection closing...\n");
|
printf("Connection closing...\n");
|
||||||
|
@ -240,6 +251,7 @@ DWORD WINAPI WriteToPipe(LPVOID lpParam)
|
||||||
}
|
}
|
||||||
} while (iResult > 0);
|
} while (iResult > 0);
|
||||||
|
|
||||||
|
WriteToPipe_end:
|
||||||
// Closing STDIN => cmd.exe exit
|
// Closing STDIN => cmd.exe exit
|
||||||
if (!CloseHandle(g_hChildStd_IN_Wr))
|
if (!CloseHandle(g_hChildStd_IN_Wr))
|
||||||
ErrorExit(TEXT("StdInWr CloseHandle"));
|
ErrorExit(TEXT("StdInWr CloseHandle"));
|
||||||
|
@ -247,19 +259,24 @@ DWORD WINAPI WriteToPipe(LPVOID lpParam)
|
||||||
|
|
||||||
DWORD WINAPI ReadFromPipe(LPVOID lpParam)
|
DWORD WINAPI ReadFromPipe(LPVOID lpParam)
|
||||||
{
|
{
|
||||||
DWORD dwRead, dwWritten;
|
DWORD dwRead;
|
||||||
CHAR chBuf[BUFSIZE];
|
CHAR chBuf[BUFSIZE + 1];
|
||||||
|
|
||||||
BOOL bSuccess = FALSE;
|
BOOL bSuccess = FALSE;
|
||||||
HANDLE hParentStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
|
//HANDLE hParentStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
SOCKET ClientSocket = ((PipeThreadInfo*)lpParam)->ClientSocket;
|
SOCKET ClientSocket = ((PipeThreadInfo*)lpParam)->ClientSocket;
|
||||||
HANDLE g_hChildStd_OUT_Rd = ((PipeThreadInfo*)lpParam)->Pipe;
|
HANDLE g_hChildStd_OUT_Rd = ((PipeThreadInfo*)lpParam)->Pipe;
|
||||||
|
|
||||||
int iSendResult;
|
int iSendResult;
|
||||||
|
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
bSuccess = ReadFile(g_hChildStd_OUT_Rd, chBuf, BUFSIZE, &dwRead, NULL);
|
bSuccess = ReadFile(g_hChildStd_OUT_Rd, chBuf, BUFSIZE, &dwRead, NULL);
|
||||||
if (!bSuccess || dwRead == 0) break;
|
if (!bSuccess || dwRead == 0) break;
|
||||||
|
printf("STDOUT: %s\n", chBuf);
|
||||||
|
|
||||||
|
chBuf[dwRead] = '\0';
|
||||||
|
|
||||||
iSendResult = send(ClientSocket, chBuf, dwRead, 0);
|
iSendResult = send(ClientSocket, chBuf, dwRead, 0);
|
||||||
if (iSendResult == SOCKET_ERROR) {
|
if (iSendResult == SOCKET_ERROR) {
|
||||||
|
@ -268,9 +285,6 @@ DWORD WINAPI ReadFromPipe(LPVOID lpParam)
|
||||||
WSACleanup();
|
WSACleanup();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
// Write to console
|
|
||||||
bSuccess = WriteFile(hParentStdOut, chBuf,
|
|
||||||
dwRead, &dwWritten, NULL);
|
|
||||||
if (!bSuccess) break;
|
if (!bSuccess) break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
10
server.h
10
server.h
|
@ -12,11 +12,7 @@
|
||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
#include <ws2tcpip.h>
|
#include <ws2tcpip.h>
|
||||||
|
|
||||||
|
#define DEFAULT_PORT "50113"
|
||||||
|
|
||||||
// Defined functions
|
// Defined functions
|
||||||
void StartShellServer();
|
void StartShellServer();
|
||||||
//void CreatePipes();
|
|
||||||
//void CreateChildProcess(void);
|
|
||||||
//DWORD WINAPI WriteToPipe(LPVOID lpParam);
|
|
||||||
//DWORD WINAPI ReadFromPipe(LPVOID lpParam);
|
|
||||||
//void ErrorExit(PCTSTR);
|
|
||||||
//void CreateSocket();
|
|
Loading…
Reference in a new issue