2015-01-08 118 views
-1

我是新的winsock,我在linux環境下工作,我正在編寫一個程序,客戶端將在shell服務器上連接,我無法將輸出發送到客戶端,我還沒有開發完整的客戶端,我正在使用netcat進行測試, 但是沒有得到輸出中的數據... 有人可以幫助改進此代碼?Winsock,在遠程服務器上的命令行

我該怎麼做才能讓客戶端接收到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

停止使用C風格的轉換,它們只是隱藏編譯器可以捕獲的錯誤。此外,你的問題描述幾乎是無用的,沒有錯誤信息,沒有預期的輸出,沒有最小的例子。我也猜想你正試圖一次完成太多事情,但這很難說。 –

+3

你應該解釋爲什麼你說的Linux環境和netcat的一部分(罰款是Linux),以及winsock顯示在Windows上創建'cmd.exe'子過程?你到底想用這些代碼做什麼?順便說一句,如果這是問題,對CreateProcess的調用需要初始化si和pi結構。但請確認你的問題。 –

+0

我只想知道,我該怎麼做才能讓客戶端接收到cmd命令的輸出 – Mrdk

回答

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; 
} 
+1

非常感謝你! – Mrdk

相關問題