プロが教えるわが家の防犯対策術!

sendで送られてきたデータをrecvで取得しています。
recvで取得したあと'\0'を入れないと文字化けを起こしてしまうので'\0'を入れているのですが、そうすると送信したバイト数と違ってきます。

同じバイト数にしたいのですが、いろいろ試しましたが、うまくいきません。 
ご存知の方いらっしゃいましたら、教えてください。

また、recvで受けるときは、バイト数が多くなるのは、仕方がないのでしょうか?

// ------------------ ソース --------------------

DWORD byteResult;
ofstream fileWrite;

byteResult = 0;

while(byteResult < 最大バイト数){
nResult = recv(client_s, (CHAR *)pbuff, 7000, 0); <-- 一括で最大バイト数で受信をしたいのだが、途中で文字化けを起こすので、7000バイトに区切って受信。
pbuff[nResult + 1] = '\0';

try{
fileWrite.open("D:\\suzuki\\LogOutTest\\outdir.txt", ios::app);
fileWrite << pbuff;
fileWrite.close();
}catch(CException e){
fileWrite.close();
return -1;
}
byteResult += nResult;
}
delete[] pbuff;

よろしくお願いします。

A 回答 (3件)

 この方法では、通信が終了するまで何度も何度もファイルをオープンしたりクローズしたりしなければなりません。


 ios::appの指定により、ファイルの末尾に受信データを追加するため、(pbuff[nResult+1]をpbuff[nResult]に書き換えさえすれば)確かに正常に動作するかもしれませんが、あまり好ましくはないでしょう。
 また、通信が途中で切れた場合の処理が行われていません。通信が途中で切れると、recv関数は-1を返しますから、pbuff[nResult]のところでセグメンテーションエラーが生じてプログラムは強制終了させられます。これではバグです。

また、recv関数は必ずしも受信長が指定した値にまで達しているとは限りません。そこで、recv関数を使って、lenまで受信する関数receiveを紹介します。(私のホームページから...)
http://www.multisoft-lab.com/voicechat/socket.html

int receive(SOCKET s,char* buf,int* len){
 int revd_size;
 int tmp;
 revd_size=0;
 while(revd_size<*len){
  tmp=recv(s,buf+revd_size,*len-revd_size,0);
  if(tmp==SOCKET_ERROR){ /* エラーが発生 */
   *len=received;
   return SOCKET_ERROR;
  }
  if(tmp==0){ /* ソケットが切断された */
   *len=received;
   return 0;
  }
  received+=tmp;
 }
 *len=received;
 return received;
}

// ---------------------------
recv関数に着目してください。
recv(s,buf+revd_size,*len-revd_size,0);

となっていますね。
これは、受信データをbufに継ぎ足すための工夫です。

参考URL:http://www.multisoft-lab.com/voicechat/socket.html
    • good
    • 0
この回答へのお礼

ありがとうございます。

いろいろ調べながら作成しているのですが、VC++ も経験がなく手こずっていました。
参考URLを再度勉強して、もっと上達したいと思います。

大変ありがとうございました。

お礼日時:2005/06/08 23:13

何をもって、「文字化けを起こしてしまう」と判断されているのでしょう?



出力ファイル(outdir.txt)を見て判断するのは間違いです。
pbuffに {'a', 'b', 'c', 0, 'd', 'e'}が入っている場合、
fileWrite << pbuff
ってやると
"abc"しか格納されませんよ。

また、仮にすべて平文のテキストの送受信をしているとしても
>pbuff[nResult + 1] = '\0';
これはマズイです。
pbuff[nResult] = '\0';
ではないでしょうか。
    • good
    • 0
この回答へのお礼

失礼致しました。 解決いたしました。

お礼日時:2005/06/08 10:52

なぜ文字化けするんでしょうか?



また、このままだと2回目以降のrecvでpbuffが上書きされますけど、問題ありませんか?

この回答への補足

>また、このままだと2回目以降のrecvでpbuffが上書きされますけど、問題ありませんか?

pbuffに追加する方法ってあるのですか?

補足日時:2005/06/08 10:53
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!