Linux環境用のC言語でアプリを作りました。このアプリは動作しますが、しばらくすると (5 時間前後)、パフォーマンスが不安定になります。これが背景です。5分ごとにソケット(私のアプリ)を介してデータを送信するリモートコンピューター(400台程度)があります。すべてのプロセスはループであり、一日中機能する必要があります。アプリは最初にデータを送信し (存在する場合)、次にデータを受信します (存在する場合)。私のアプリは、いくつかの引数を持つサーバー側のように動作するか、他の引数を持つクライアント側のように動作します。サーバー モードとして動作するアプリは、リッスン状態の後、クライアント接続のみを待機します。クライアントが接続されると、クライアントモードのアプリは、データが送信されることを示すメッセージを送信し、サイズと名前が連結された新しいメッセージをサーバー側に送信します (常に 64 バイトを送信し、私のアプリは64バイトを書き込み、反対側では64バイトを読み取ります)、データ(ファイル)を送信します。サーバーは、受信するファイルのサイズと名前のメッセージ (64 バイト) を読み取り、メッセージを分割して、サイズを変数に、ファイル名を other に格納し、ファイル データを受信した後に受け取ります。変数に保存されているサイズと読み取ったデータのサイズを比較し、すべて問題がなければ、サーバーはメッセージを送信し、データを受信前の名前で新しいファイルに保存します。このようにして、最後のファイルが送信されるまで続けます。次に、サーバーはメッセージを送信し、データを受信前の名前で新しいファイルに保存します。このようにして、最後のファイルが送信されるまで続けます。次に、サーバーはメッセージを送信し、データを受信前の名前で新しいファイルに保存します。このようにして、最後のファイルが送信されるまで続けます。
私のアプリが開発段階にあったとき、数時間後にメッセージが破損していることに気付きました。つまり、メッセージが不完全であるか、より多くのデータ (おそらく次のデータ) があることを意味します。だからファイルデータも。では、どうすれば同じソケットを介してファイル データを送信できますか?? 注: メッセージを送受信するためのバッファーと、ファイル データを送受信するためのバッファーがあります。
その他の質問: 元のコード:
int copydata(int readfd, int writefd, int offset, int bytes) {
char buffer[4096];
int crbytes = 0, cwbytes = 0, trbytes = 0, twbytes = 0;
if (offset) {
if (lseek(readfd, offset, SEEK_CUR) < 0) {
return -1;
}
}
while ((crbytes = read(readfd, buffer, bytes)) > 0) {
if (crbytes < 0) {
return -1;
}
trbytes += crbytes;
//printf("dbgmsg::Readed data <%dB> | Total readed data <%dB>\n", crbytes, trbytes);
while (crbytes > 0) {
cwbytes = write(writefd, buffer, crbytes);
if (cwbytes < 0) {
return -1;
}
twbytes += cwbytes;
crbytes -= cwbytes;
//printf("dbgmsg::Written data <%dB> | Total written data <%dB>\n", cwbytes, twbytes);
}
}
return twbytes;
}
このコードは、ファイル データの送受信に使用されます。データを送信する側は、送信したいファイルのファイル記述子を使用して (読み取り) <readfd>
、ソケットのファイル記述子に書き込みます (書き込み) <writefd>
。データを受信する側は<readfd>
、ソケット ファイル記述子から読み取るために使用し、<writefd>
データを書き込みたいファイルからファイル記述子に書き込みます。この関数を使用する前に他のメッセージが送信された場合、クライアントとサーバーの両方が内部の「while ループ」の最後でスタックします。つまり、クライアントはすべてのファイル データを送信し、サーバーはすべてのファイル データを受信します (このポイント、受信したデータが完了したことをどのように知ることができますか? 受信したファイルを開くことができるため)。エラーはなく、「目的のタイプのメッセージがありません」という 1 つだけです。この関数の前にメッセージを送信しなかった場合、すべて正常に機能します。この小さな問題をスキップするために、コードを変更し、ファイル サイズも引数として渡し、2 つの while と if 構造の間に書き込みます。
int copydata(int readfd, int filesz, int writefd, int offset, int bytes) {
char buffer[4096];
int crbytes = 0, cwbytes = 0, trbytes = 0, twbytes = 0;
if (offset) {
if (lseek(readfd, offset, SEEK_CUR) < 0) {
return -1;
}
}
while ((crbytes = read(readfd, buffer, bytes)) > 0) {
if (crbytes < 0) {
return -1;
}
trbytes += crbytes;
//printf("dbgmsg::Readed data <%dB> | Total readed data <%dB>\n", crbytes, trbytes);
while (crbytes > 0) {
cwbytes = write(writefd, buffer, crbytes);
if (cwbytes < 0) {
return -1;
}
twbytes += cwbytes;
crbytes -= cwbytes;
//printf("dbgmsg::Written data <%dB> | Total written data <%dB>\n", cwbytes, twbytes);
}
if (twbytes == filesz) { break; }
}
return twbytes;
}
前もってありがとう、そして私の英語でごめんなさい!!