8

STDOUTとSTDERRをソケットにリダイレクトしようとしています。

やった:

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

どういうわけか、それは出力の最初の小さな部分だけを示しました。

たとえば、lsまたはmkdirを実行しようとすると、「mkdir」に表示されました。

どうしたの?

以下を試してみましたが、STDOUTまたはSTDERRのいずれかしかリダイレクトできません

close(1);
dup(newsock);

どうもありがとう。

4

4 に答える 4

12

の使用は問題ないようにdup2()見えるので、問題はおそらく他の場所にあります。私がテストのために一緒に投げた単純なプログラムには、あなたが経験している問題がないので、簡潔にするためにいくつかのエラーチェックを省略して、そのコア( fork()/領域の周り)を調べます。execvp()

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 */
  }
}

上記は非常に基本的なサーバー(一度に1つのクライアントのみ)のコアであり、接続を受信すると、コマンドを実行するための新しいプロセスをフォークし、そのstderrとstdoutをソケットを介してクライアントに送信します。うまくいけば、問題を調べることで問題を解決できますが、コードの機能を理解せずにコードをコピーするだけではいけません。

最初にtelnetクライアントに接続してテストしてみてください...telnetで動作するが、クライアントプログラムでは動作しない場合は、クライアントプログラムの問題を探してください。

于 2011-11-12T04:16:09.697 に答える
4

の使用法dup2は正しいです。データがリモートピアによってまだ受信されておらず、これに割り当てられたカーネルバッファがいっぱいである可能性があるため、書き込み呼び出しは、与えているバッファ全体を書き込んでいません。通常のバッファサイズは64KBです。受信者がデータを受信して​​いることを確認し、書き込みをループでラップする必要があります。MSG_SENDALLまたは、、、およびsendsyscallを使用します。

于 2011-11-12T00:18:19.800 に答える
1

ページをもう一度読むman dup2(抜粋):

 SYNOPSIS
   int dup2(int oldfd, int newfd);

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

だからそれはdup2 (STDOUT_FILENO, newsock);

于 2011-11-11T23:46:21.830 に答える
0

問題は、stderrとstdoutが一部のシステムで同じものの1つであるということだと思います

于 2020-12-01T10:37:39.267 に答える