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;
よろしくお願いします。
No.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
ありがとうございます。
いろいろ調べながら作成しているのですが、VC++ も経験がなく手こずっていました。
参考URLを再度勉強して、もっと上達したいと思います。
大変ありがとうございました。
No.2
- 回答日時:
何をもって、「文字化けを起こしてしまう」と判断されているのでしょう?
出力ファイル(outdir.txt)を見て判断するのは間違いです。
pbuffに {'a', 'b', 'c', 0, 'd', 'e'}が入っている場合、
fileWrite << pbuff
ってやると
"abc"しか格納されませんよ。
また、仮にすべて平文のテキストの送受信をしているとしても
>pbuff[nResult + 1] = '\0';
これはマズイです。
pbuff[nResult] = '\0';
ではないでしょうか。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Excel(エクセル) Excelにて、フォルダ内のTextファイルをマクロで統合すると文字化けしてしまう時の解消コード 4 2023/01/01 07:32
- PHP 文字列を段落で分ける方法を教えて下さい。 2 2023/03/09 10:03
- UNIX・Linux Postfixでドコモメールに送信すると届くまで10分ぐらいかかる 6 2023/03/05 13:56
- その他(社会・学校・職場) 長くなるのですが、バイトのことで相談があります。 私は専門学生です。介護のバイトをしています。 面接 6 2022/12/20 11:29
- アルバイト・パート 大学生になって、4月からスーパーのバイトを始めました。そこは人手があまり足りておらず色々と忙しいとこ 3 2022/05/17 00:29
- その他(悩み相談・人生相談) 大学生でバイトを辞めました。アドバイスお願いします。 3 2022/08/18 14:02
- 会社・職場 バイトでミスをしまくる件について。 私は5年間続けているバイトがあります。その仕事は雑貨を売る仕事で 5 2023/02/24 07:17
- 会社・職場 質問です。 私が派遣で仕事をしていた所で知り合ったバイトのおじさんの話です。多分40代くらいです。 5 2022/12/12 23:36
- 片思い・告白 送信取り消ししてもいいですか? 2人とも同じバイト先で、相手はフリーターでアルバイトのみの実家暮らし 8 2023/03/29 20:59
- 会社・職場 大学生です。 バイトに入れると言ったが入れなくなりました。 私はバイトで電話の予約を受けていました。 1 2022/04/01 01:45
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
C# シリアル通信でデータ受信...
-
winsock recvでデータの取得方法
-
RS232C通信(PC⇔PLC)
-
ClearCommError呼び出し時のCE_...
-
WinsockAPIのrecvfromの受信デ...
-
Linuxでのシリアル通信について...
-
winsockの動作について。
-
「スイッチングハブのバッファ...
-
VB2005でWin32APIを用いてRS-23...
-
rs232cでの受信データ(mscomm)...
-
Macターミナルで実行中のプログ...
-
逆コンパイルと逆アセンブルの...
-
緯度、経度の 10進法と 60進法...
-
イラストレーターCS4のシリアル...
-
C言語で、メモリを解放しないで...
-
【C言語】再帰が時間がかかる...
-
Excelでのセル内容の高速消去方法
-
バックグラウンドのプロセスの...
-
API関数 GetExitCodeProcess
-
3のつく数字と3の倍数のみを表...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
C# シリアル通信でデータ受信...
-
winsockでソケット通信の開発を...
-
socket: recvはいつ,どれだけ...
-
SocketのSend関数でのCLOSEの検...
-
シリアル通信の出力バッファと...
-
WriteFile()でのデータ送信がで...
-
RS232C通信(PC⇔PLC)
-
シリアルポート通信
-
ソケット通信内 read関数について
-
Linuxでのシリアル通信について...
-
SerialPortのDataReceivedイベ...
-
「スイッチングハブのバッファ...
-
RS-232Cでバイナリデータを受信...
-
Connection reset by peer
-
UDP処理のエラーについて
-
VB2005でWin32APIを用いてRS-23...
-
シリアル通信エラー
-
winsockの動作について。
-
シリアル通信 大きいサイズの...
-
VB2010 シリアル受信した情報を...
おすすめ情報