2011-03-18 60 views
2

我想製作客戶端服務器程序,其中服務器是主進程,客戶端是子進程。在客戶端,我想將stdout和stderr流子進程重定向到套接字。在服務器中,我想從套接字文件描述符中讀取數據並從中讀取數據。在互聯網上有很多關於套接字的信息,但我沒有發現任何通過用於Windows的套接字的父子IPC的例子。如何在winapi中將子進程的stdout(stderr)重定向到套接字?

如果可能的話請在這裏發佈一個簡單的代碼來解決我的問題(或部分)。 MSDN的鏈接也可以提供幫助,但我想我已經在那裏查看了所有內容,但沒有找到我想要的內容。

P.S.請不要建議管道。我想通過套接字來做到這一點。

+0

這將是非常具體的實現。我將假設windows是唯一的平臺和操作系統要求。您願意使用哪種編譯器,IDE和庫? – AJG85 2011-03-18 16:22:47

+0

我正在使用visual studio。我想使用standart庫和winapi,作爲我更喜歡socket2的套接字。但也可以使用cygwin庫。 – 2011-03-18 16:25:41

+0

哪部分你有問題 - 綁定+監聽套接字,連接套接字或重定向IO? – Rup 2011-03-18 16:27:02

回答

1

看看Netcat如果你可以使用它或在sourceforge的某處找到windows版本的源代碼,可能會使用管道攔截stdin/stdout,並使用這些管道發送和讀取套接字。

我知道你說沒有管道,但沒有其他的方式來做到這一點只有Windows API。你需要至少大概如下:

CreatePipe

WriteFile

ReadFile

+0

謝謝。但我已經通過管道做到了這一點))但是沒有問題。管道不支持select()那就是爲什麼我需要套接字。 – 2011-03-18 16:45:38

+0

您可以使用重疊的I/O模型和'WaitForMultipleObjects'從多個管道讀取或管理。它不像套接字列表中的Select()那麼好,但是它是一種放棄的方式。你有多少客戶運行,你需要重定向到服務器? – AJG85 2011-03-18 17:00:35

+0

是@ AJG85我也可以這樣做。但這是另一個問題。如果我這樣做,那麼我需要以非阻塞模式讀取表單管道。在Windows中,我無法生成文件HANDLES非阻塞我只能通過低級別的ReadFile函數以nonblocing模式讀取。但是我想從這個句柄中創建FILE *然後通過fgets讀取。 – 2011-03-18 17:13:25

0

這就好比試圖救火其啓動後,當你要試圖阻止首先是火災。

由於您是server.exe和client.exe的宣稱作者,而不是嘗試捕獲stdout/stderr,並在此時將其重定向到套接字,因此您應該重新設計客戶端,重新捕捉髮往stdout的文本,然後轉到stdout。

在這一點上,你可以發送輸出文本到BOTH標準輸出和一個套接字,如果你願意。

編輯:忽略上半部分,因爲你後來說你不是客戶的作者。

好了,第二次嘗試:

因爲你是產卵的「真實」的客戶端,使用「假」的客戶,你爲什麼不只是攔截上的「假貨」標準輸入「真實」的客戶端的標準輸出客戶端(打開管道)。然後有 「假」 的客戶端將數據發送回插座..

+0

我不是真正的客戶端的作者。我只是虛假客戶端的作者,它應該只連接到服務器,然後自己產生真正的客戶端,stdout和stdoerr必須重定向。 – 2011-03-18 16:54:01

+0

@J T查看@ AJG85s的評論回答 – 2011-03-18 17:03:33

+0

這個想法並不是在客戶端和服務器之間打開管道,只是在「假」客戶端和「真實」客戶端之間打開管道。 「假」客戶端仍然會通過套接字發送其數據,因此您的服務器仍然可以複用所有傳入請求並僅在一個進程上運行。 – 2011-03-18 17:07:43

0

假設:

server talks with client 

client spawns child 

下面是從MSDN一個例子不幸的是創建一個Child Process with Redirected IO

,你必須使用管道將子程序中的IO傳給客戶端。沒有ifs,ands或buts關於它。

然後你可以使用類似下面來獲取信息到服務器:

客戶端通訊科環:

while (/* files are open */) { 
    DWORD dwRead; 
    CHAR chBuf[1024]; memset(chBuf, 0, 1024); /* always initialize your memory! */ 
    BOOL bSuccess = FALSE; 

    /* read data from child pipe */ 
    ReadFromFile(g_hSChildStd_IN_Rd, chBuf, 1024, &dwRead, NULL);  

    /* send data via windows sockets to the remote server connection 
     represented by serverSocketHandle */ 
    send(serverSocketHandle, chBuf, dwRead, 0); 
} 

你的客戶,實際上成爲STDOUT/ERR管之間的翻譯和一個TCP套接字。

+0

@Chris你想說什麼? – 2011-03-18 17:04:12

+0

我在問題中寫道不建議管道。 – 2011-03-18 17:08:10

+0

Mihran,如果你不能修改可執行的「真實」客戶端,你必須以某種方式攔截STDOUT/ERR。你真的應該重新考慮使用管道。 – 2011-03-18 17:11:51

0

我知道支持這個的唯一環境是Cygwin。他們是開源的 - 嘗試仔細閱讀他們的代碼以獲取想法。不過,這確實是非常令人討厭的,其中包括像四處抽線的東西。

相關問題