Winsock,远程服务器上的命令行

时间:2015-01-08 06:44:59

标签: c++ winsock

我是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;
}

1 个答案:

答案 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;
}