2011-09-12 5 views
1

私は2つのファイルを聴くサーバプログラムを作成する必要がある宿題としてかなり大きなプロジェクトを作成しています。fifo上のsyscallがブロックされていませんか?

私は怒っている何かがあります:私はクライアントとサーバー間のいくつかの書き込み/読み取りから構成されている操作を行うたびに、クライアント上でFIFOを閉じると、まだそれらのFIFOを開いたままにしている人がいるということです。

このため、サーバーは各操作の後に64バイトを読み込もうとしましたが、失敗しました(0バイトを読み取る)。操作ごとに1つだけの時間がこの事が起こる、それはそれは、クライアントへの任意の問題を作成しませんが、それは本当に奇妙だと私はバグのこれらのタイプを憎む64バイト

を読み取ろうと守らない

私はそれがオープン/クローズに関連する問題であり、クライアントがロックを使用しているという事実であると考えてください。

注意、オープン操作に使用されるフラグは、この擬似コードのテキスト

Serverの動作に指定されています。私は直接投稿することはできません

Set a lock on Fifo(1) (waiting if there is already one) 
Set a lock on Fifo(2) (same as before) 
Open Fifo(1) for WRITING (O_WRONLY) 
Open Fifo(2) for READING (O_RDONLY) 
Do some operations 
Close Fifo(1) 
Close Fifo(2) 
Get lock from Fifo(1) 
Get lock from Fifo(2) 

Open Fifo(1) for READING (O_RDONLY) 
Open Fifo(2) for WRITING (O_WRONLY) 
Do some operations 
Close Fifo(1) 
Close Fifo(2) 

クライアントの動作プロジェクトはかなり大きく、私は直接システムコールを使用しないので、ネットワーキングに使用される関数を除いて、コードです。ここには:

int Network_Open(const char* path,int oflag) 
{ 
    return open(path,oflag); 
} 

ssize_t Network_IO(int fifo,NetworkOpCodes opcode,void* data,size_t dataSize) 
{ 
    ssize_t retsize = 0; 
    errno = 0; 

    if (dataSize == 0) return 0; 

    while ((retsize = (opcode == NetworkOpCode_Write? write(fifo,data,dataSize) : read(fifo,data,dataSize))) < 0) 
    { 
     if (errno != EINTR) break; 
    } 

    return retsize; 
} 

Boolean Network_Send(int fifo,const void* data,size_t dataSize) 
{ 
    return ((ssize_t)dataSize) == Network_IO(fifo,NetworkOpCode_Write,(void*)data,dataSize); 
} 

Boolean Network_Receive(int fifo,void* data,size_t dataSize) 
{ 
    return ((ssize_t)dataSize) == Network_IO(fifo,NetworkOpCode_Read,data,dataSize); 
} 

Boolean Network_Close(int fifo) 
{ 
    if (fifo >= 0) 
     return close(fifo) == 0; 
} 

ありがとう、ありがとうございます。

EDIT 1:

クライアント出力:http://pastie.org/2523854 サーバ出力(straceの):http://pastie.org/2523858

+0

Network_Openで開くためにどのフラグを渡していますか? – asm

+0

O_RDONLYは書き込み用、O_WRONLYは書き込み用、その他は –

答えて

2

read()からのゼロバイトの結果は、他のプロセスが終了したことを意味します。これで、サーバーは元のファイル記述子を閉じて、次のクライアントを提供するためにFIFOを再オープンする必要があります。新しいファイル記述子での作業を開始すると、ブロック操作が再開されます。

これは、動作するはずの方法です。

AFAIKは、ゼロバイトを取得した後、さらにファイルディスクリプタを読み込もうとすると0バイトを永久に(またはファイルディスクリプタを閉じるまで)返します。別のプロセスがFIFOをオープンしても、元のファイル記述子はEOFを示し続けます(他のクライアントプロセスは、サーバプロセスがFIFOを読み込み待機するのを待っていません)。

3

ゼロバイト(読み取り(ブロッキング)から返された)は、すなわち、ファイルの終わりを示しますもう一方の端がFIFOを閉じていることを示します。マンページを読んで読んでください。

+0

私はこれを理解できますが、書き込みモードで相手側に誰もない場合、私のサーバが最初のFIFOをオープンするのはなぜですか? –

+0

Mh yeaですが、私はブロックモードでディスクリプタを開いています。そのため、この動作を理解できません。 –

+1

コード内の何もこの動作を示していません。 FIFOを開いてデータを読んで、最終的に0を返すとすべてが完全に正常です。読んで0を返すときはどうしますか?あなたは、あなたが再びFIFOを開くことを私たちに伝えていますか?クライアントが再び開く前に?あなたのアプリケーションで 'strace'を実行して何が起こるかを確認してください。 – nos

関連する問題