2011-04-04 35 views
2

我有一個打開的套接字,它連接一個客戶端和服務器。更改文件描述符以將STDOUT管道傳輸到套接字?

我正在實現遠程執行,所以我想要更改文件描述符表,以便通常會轉到stdout的調用實際上通過套接字輸出到客戶端。

現在我有服務器分叉,然後使用system()命令來執行任何命令。

操作文件描述符表我需要做些什麼?

這是我正在使用的代碼:

我正在使用select。我使用的套接字是由accept調用返回的套接字(這是所有服務器端)。

  dup2(S,1); 

      int retval = fork(); 
      if (retval > 1) 
      { 
      system(receive.text); 
      return 0; 
      } 

現在這樣的結果,是沒有文本打印服務器(因此它顯然沒有涉足服務器的標準輸出),但也不是顯示在客戶端上的任何東西)。

我是否還需要在客戶端做更多的事情才能解決問題(比如recv()調用?),並且我使用正確的套接字嗎?

謝謝。

回答

3

通常的機制是dup2(2)

#include <unistd.h> 

int dup(int oldfd); 
int dup2(int oldfd, int newfd); 

dup(2)通話將指定的文件描述符複製到編號最小的開放式文件描述符。這是歷史機制,仍然有效,但它並不容易指定文件描述符號碼。因此引入了dup2(2)以允許指定兩個文件描述符。

你可以使用這樣的:

int s = /* connect() or accept() */ 
int ret = dup2(s, 1); 
/* exec() */ 
+0

是1 stdout還是0? – Blackbinary 2011-04-04 01:31:40

+0

@blackbinary,你讓我很後悔只是使用一個整數而不是'STDOUT_FILENO' :) - '0'是stdin,'1'是stdout,而'2'是stderr;由於shell重定向的'2>&1'風格,我發現它更容易記憶 - 您幾乎不會重定向'0',因此必須輸入。 :) – sarnold 2011-04-04 01:37:00

+0

好吧,那麼我看到的頁面有一個錯字(有0而不是1)。我將在原文中發佈一些代碼,因爲它仍然不正確。 – Blackbinary 2011-04-04 01:41:25

0

的問題是,僅僅system保持父母的文件描述符,所以像你想它不能正常工作。你可以使用popen,但它很醜。你真的應該自己編寫代碼forkexecsystem幾乎總是一個錯誤。

+0

啊,我認爲這是相當的,我只是在節省時間。所以,如果我自己叉和執行,它應該工作? – Blackbinary 2011-04-04 01:57:31

+0

因此,如果使用dup2來更改文件描述符,爲什麼我不能只使用printf(因爲現在將指向套接字)?它沒有工作,但我想知道爲什麼(我似乎無法使用fork和exec方法)。 – Blackbinary 2011-04-04 02:07:59

相關問題