2011-04-04 108 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

相关问题