将 STDOUT 和 STDERR 重定向到 C 中的套接字?

发布于 2024-12-15 02:31:02 字数 375 浏览 0 评论 0原文

我正在尝试将 STDOUT 和 STDERR 重定向到套接字。

我做到了:

if(fork() == 0)
{
   dup2(newsock, STDOUT_FILENO);
   dup2(newsock, STDERR_FILENO);
   execvp();
}

不知何故,它只显示了输出的前一小部分。

例如,当我尝试执行 ls 或 mkdir 时,它显示在“mkdir”上。

有什么问题吗?

我尝试了以下方法,但我只能重定向 STDOUT 或 STDERR 之一,

close(1);
dup(newsock);

非常感谢。

I am trying to redirect STDOUT AND STDERR to a socket.

I did:

if(fork() == 0)
{
   dup2(newsock, STDOUT_FILENO);
   dup2(newsock, STDERR_FILENO);
   execvp();
}

Somehow, it only showed the first little part of the output.

for example, it showed on "mkdir" when I try to execute ls or mkdir.

What's the problem?

I tried the flollowing it works, but I can only redirect one of STDOUT or STDERR

close(1);
dup(newsock);

Thanks a lot.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

ゞ记忆︶ㄣ 2024-12-22 02:31:02

您对 dup2() 的使用看起来很好,因此问题可能出在其他地方。我组合在一起测试的简单程序没有您遇到的问题,因此我将仅介绍它的核心(围绕 fork()/execvp()< /code> 区域),为简洁起见,省略了一些错误检查:

int    lsock, /* listening socket */
       csock; /* active connection's socket */
pid_t  cpid;  /* child process ID from fork() */
char   *cmd = "somecommand";
char   *cmd_args[] = { "somecommand",
                       "firstarg",
                       "secondarg",
                       "howevermanyargs",
                       NULL }; /* note: last item is NULL */
/*  ... 
    call socket(), bind(), listen(), etc.
    ... */

for (;;) {  /* loop, accepting connections */
  if ( (csock = accept( lsock, NULL, NULL )) == -1) exit(1);
  cpid = fork();
  if (cpid < 0) exit(1);  /* exit if fork() fails */
  if ( cpid ) {
    /* In the parent process: */
    close( csock ); /* csock is not needed in the parent after the fork */
    waitpid( cpid, NULL, 0 ); /* wait for and reap child process */
  } else {
    /* In the child process: */
    dup2( csock, STDOUT_FILENO );  /* duplicate socket on stdout */
    dup2( csock, STDERR_FILENO );  /* duplicate socket on stderr too */
    close( csock );  /* can close the original after it's duplicated */
    execvp( cmd, cmd_args );   /* execvp() the command */
  }
}

上面是一个非常基本的服务器(一次只有一个客户端)的核心,当它收到连接时,分叉一个新进程来运行命令并发送其stderr 和 stdout 通过 插座。希望您可以通过检查来解决您的问题——但不要在不了解代码用途的情况下就复制代码。

首先尝试通过与 telnet 客户端连接进行测试...如果它适用于 telnet 但不适用于您的客户端程序,则查找客户端程序中的问题。

Your use of dup2() looks fine, so the problem is probably elsewhere. The simple program I threw together to test with does not have the issues you are experiencing, so I'll just go over the core of it (around the fork()/execvp() area) with some error checking omitted for brevity:

int    lsock, /* listening socket */
       csock; /* active connection's socket */
pid_t  cpid;  /* child process ID from fork() */
char   *cmd = "somecommand";
char   *cmd_args[] = { "somecommand",
                       "firstarg",
                       "secondarg",
                       "howevermanyargs",
                       NULL }; /* note: last item is NULL */
/*  ... 
    call socket(), bind(), listen(), etc.
    ... */

for (;;) {  /* loop, accepting connections */
  if ( (csock = accept( lsock, NULL, NULL )) == -1) exit(1);
  cpid = fork();
  if (cpid < 0) exit(1);  /* exit if fork() fails */
  if ( cpid ) {
    /* In the parent process: */
    close( csock ); /* csock is not needed in the parent after the fork */
    waitpid( cpid, NULL, 0 ); /* wait for and reap child process */
  } else {
    /* In the child process: */
    dup2( csock, STDOUT_FILENO );  /* duplicate socket on stdout */
    dup2( csock, STDERR_FILENO );  /* duplicate socket on stderr too */
    close( csock );  /* can close the original after it's duplicated */
    execvp( cmd, cmd_args );   /* execvp() the command */
  }
}

The above is the core of a very basic server (only one client at a time) that, when it receives a connection, forks a new process to run a command and sends its stderr and stdout to the client over the socket. Hopefully you can solve your problem by examining it -- but don't just copy the code without understanding what it does.

Try testing by connecting with a telnet client first... if it works with telnet but not with your client program, then look for problems in your client program.

轻许诺言 2024-12-22 02:31:02

您对 dup2 的使用是正确的。您的写入调用不会写入您提供给它们的整个缓冲区,因为远程对等方尚未收到数据,并且为此分配的内核缓冲区可能已满。典型的缓冲区大小为 64KB。您应该确保接收器正在接收数据,并将您的写入包装在循环中。或者使用 MSG_SENDALLsend 系统调用。

Your usage of dup2 is correct. Your write calls are not writing the entire buffer you're giving them, as the data hasn't been received by the remote peer yet, and the kernel buffer allocated for this is likely full. The typical buffer size is 64KB. You should make sure that the receiver is receiving the data, and wrap your writes in a loop. Alternatively use MSG_SENDALL, and the send syscall.

微暖i 2024-12-22 02:31:02

再次阅读 man dup2 页面(摘录):

 SYNOPSIS
   int dup2(int oldfd, int newfd);

 DESCRIPTION
   dup2() makes newfd be the copy of oldfd, closing newfd 

所以应该是 dup2 (STDOUT_FILENO, newsock);

Read again the man dup2 page (excerpts):

 SYNOPSIS
   int dup2(int oldfd, int newfd);

 DESCRIPTION
   dup2() makes newfd be the copy of oldfd, closing newfd 

So it should be dup2 (STDOUT_FILENO, newsock);

夜声 2024-12-22 02:31:02

我认为问题在于 stderr 和 stdout 在某些系统上是相同的之一

I think the problem is that stderr and stdout are one of the same on some systems

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文