- ベストアンサー
winsock recvでデータの取得方法
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; よろしくお願いします。
- みんなの回答 (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に継ぎ足すための工夫です。
その他の回答 (2)
- mssine
- ベストアンサー率24% (38/156)
何をもって、「文字化けを起こしてしまう」と判断されているのでしょう? 出力ファイル(outdir.txt)を見て判断するのは間違いです。 pbuffに {'a', 'b', 'c', 0, 'd', 'e'}が入っている場合、 fileWrite << pbuff ってやると "abc"しか格納されませんよ。 また、仮にすべて平文のテキストの送受信をしているとしても >pbuff[nResult + 1] = '\0'; これはマズイです。 pbuff[nResult] = '\0'; ではないでしょうか。
お礼
失礼致しました。 解決いたしました。
- real_neo
- ベストアンサー率12% (10/83)
なぜ文字化けするんでしょうか? また、このままだと2回目以降のrecvでpbuffが上書きされますけど、問題ありませんか?
補足
>また、このままだと2回目以降のrecvでpbuffが上書きされますけど、問題ありませんか? pbuffに追加する方法ってあるのですか?
お礼
ありがとうございます。 いろいろ調べながら作成しているのですが、VC++ も経験がなく手こずっていました。 参考URLを再度勉強して、もっと上達したいと思います。 大変ありがとうございました。