0

ある PC から別の PC にデータを転送するソケット プログラムを作成していますが、処理するバイナリ データを相手側に送信するときに問題が発生します。この場合、データ ソケットがデータを送信している間、メッセージ ソケットをリッスンするスレッドが 1 つ必要です。だから私は問題がソケットではないことを発見しました。データを画面に書き込もうとすると問題が発生します(今回はソケットはありません)。だから私は fflush(stdout) を使用してデータをフラッシュしようとしましたが、うまくいきませんでした。コードはこのように機能します。

Initialize the 2 sockets.
Initialize 2 threads.
  One to get the data back through the data socket.
  The other send the data.    
And while sending all the data one pthread_join(m_thread2) in the main function, because the data can take 1 second to be processed or one hour so i keep the program alive this way.

私は 2 つのスレッドを使用して読み取りと画面への送信を行う小さなバージョンを作成しました。

コード:

#include <iostream>
#include <fstream>
#include <string.h>

using namespace std;

const int RCVBUFSIZE=2000;
char echoString[RCVBUFSIZE];
int recvMsgSize;
static void * _sendExec(void *instance);
static void * _recvExec(void *instance);
int main(){
  pthread_t m_thread, m_thread2;
  int merror, merror2;
  merror=pthread_create(&m_thread, NULL, _sendExec, NULL);
  merror2=pthread_create(&m_thread2, NULL, _recvExec, NULL);
  pthread_join(m_thread2, NULL);
}
static void * _sendExec(void *instance){
  int size;
  for(;;){
    while((size=read(fileno(stdin), echoString, RCVBUFSIZE))>0){
       write(fileno(stdout), echoString, size);
    }
    fflush(stdin);
    fflush(stdout);
    pthread_exit(0);
  }
}
static void * _recvExec(void *instance){
  while(1){
     //recvMsgSize=msgTmp->recv(buffer, RCVBUFSIZE)
     write(fileno(stdout), "", 0);
     sleep(1);
  }
}

試しcat file.tar.gz | ./a.out | tar -zvtてみると、すべてのデータが画面に表示されているわけではないことがわかります。メインに置くと、pthread_join を削除しても問題ありません。問題は、データを元に戻す必要があり、時間がかかることです。それは私がするのと同じですcat file.tar.gz | ssh root@server "tar -zvt"。問題は、recvExec を使用してすべてのデータを受信した後に sendExec を強制終了できることですが、問題を説明するために、コードを変更してソケット部分を削除した後、stdin をフラッシュするだけです。

ありがとう

4

1 に答える 1

1

あなたの例でtarは、ファイルの終わりの表示を提供しないため、さらに入力を待っています。これを試して:

static void * _sendExec(void *instance){
  int size;
  for(;;){
    while((size=read(fileno(stdin), echoString, RCVBUFSIZE))>0){
       write(fileno(stdout), echoString, size);
    }
    fflush(stdin);
    fflush(stdout);
    fclose(stdout); // THIS IS THE LINE THAT FIXES THE SAMPLE PROGRAM
    pthread_exit(0);
  }
}

サンプル プログラムに修正を追加している間fcloseは、必ずしもメイン プログラムでそれをお勧めするわけではありません。サンプルにはまだ無限ループがあり ( 内_recvExec)、終了することはありません。

于 2012-05-04T14:19:57.057 に答える