音楽ファイルを送ろうと現在Winsockを使ってプログラムを作成しているのですが、うまく送れず、音楽をながすことができません。
ソースファイルを載せておきます。
送信
FILE *fp;
char buf[512];
char data[40000];
memset(buf, 0, sizeof(buf));
err = _wfopen_s(&fp, MUSIC, L"rb");
if (err != NULL) {
AfxMessageBox(L"読み込めませんでした");
exit(1);
}
size = fread(data, sizeof(char), 36000,fp);
sprintf_s(buf, 512, "%d", size);
res = send(pDlg->m_sock1, (char*)&buf, sizeof(buf), 0);
if(res == SOCKET_ERROR){
AfxMessageBox(L"送信できませんでした");
exit(1);
}
res = send(pDlg->m_sock1, (char*)&data, size, 0);
if(res == SOCKET_ERROR){
AfxMessageBox(L"送信できませんでした");
exit(1);
}
1
fclose(fp);
受信
FILE *fp;
int FileSize,res;
char *pFileBuffer;
res = recv(m_sock1, buf, sizeof(buf), 0);
if(res == SOCKET_ERROR)
{
AfxMessageBox(L"ファイル受信エラー1");
exit(1);
}
FileSize = atoi(buf);
pFileBuffer = (char *)calloc(FileSize, sizeof(char));
res = recv(m_sock1, pFileBuffer, FileSize, 0);
if(res == SOCKET_ERROR)
{
AfxMessageBox(L"ファイル受信エラー2");
exit(1);
}
fp = _wfopen(MUSIC, L"wb+");
if (fp == NULL) {
AfxMessageBox(L"読み込めませんでした");
exit(1);
}
res = fwrite(pFileBuffer, sizeof(char), FileSize, fp);
fclose(fp);
PlaySound(MUSIC,NULL,SND_ASYNC);
free(pFileBuffer);
pFileBuffer = NULL;
closesocket(m_sock1);
}
以上です。
送信側と受信側の両方で、デバッガを実行させながら比較するとうまく音声がなるのですが、普通にやると音が鳴りません。
どなたかアドバイスをお願いします。
非同期再生なのに即座にプログラムを終了してしまってるということなら
PlaySoundの3番目の引数をSND_SYNCにすると同期再生になります。
関係なかったらスミマセン。
send()で1回で送信したからといって、recv()でも1度で受信できるワケではない…のですが、その辺り大丈夫なんでしょうか?
最初にデータサイズを数字化して、512バイト送信しているようですが、
受信側の最初のrecvで20バイトしか受信していないかも知れません。
そうすると、次にrecv()したときにはまだ受信処理していない492バイトが残っています。
subaruさん
非同期ではないのでおそらく関係はないと思います。
でもレス感謝です。
瀬戸っぷさん
つまりrecvを何度も繰り返せば解決ってことですね。
わざわざありがとうございます。
>subaruさん
>非同期ではないのでおそらく関係はないと思います。
>でもレス感謝です。
ここで言う非同期とはソケットのことではなくPlaySoundの再生方法のことです。
PlaySoundが引数がSND_ASYNCの場合は非同期であるとMSDNに書いてあります。
>瀬戸っぷさん
>つまりrecvを何度も繰り返せば解決ってことですね。
>わざわざありがとうございます。
こちらが原因なら出来上がったファイル自体が不完全な状態になっている
のでデバッガを使わなくてもすぐ確認できるはずです。
shutdownもしてないし、どちらにしても送受信は見直す必要がありますが・・・
>つまりrecvを何度も繰り返せば解決ってことですね。
基本的にはそうなりますが…
ブロッキングモードだと受け取るデータが無くなると受信するまで(あるいは切断されるまで)戻ってきませんので注意が必要です。
TCP/IP通信関係で検索すれば事例とかあるかと思われますが。
とりあえずrecv()の戻り値はしっかり確認しましょう。
送信側を
len1 = sizeof(buf);
do{
res = send(pDlg->m_sock1, buf, sizeof(buf), 0);
if(res == SOCKET_ERROR){
AfxMessageBox(L"送信できませんでした");
exit(1);
}
len1 -= res;
}while(len1 > 0);
do{
res = send(pDlg->m_sock1, data, size, 0);
if(res == SOCKET_ERROR){
AfxMessageBox(L"送信できませんでした");
exit(1);
}
size -= res;
}while(size > 0);
受信側を
do{
res = recv(m_sock1, buf, sizeof(buf), 0);
if(res == SOCKET_ERROR)
{
AfxMessageBox(L"ファイル受信エラー1");
exit(1);
}
len -= res;
}while(len > 0);
にしてみたのですが、結果は同じでした。
ほかにできればアドバスをお願いします。
>res = recv(m_sock1, buf, sizeof(buf), 0);
recvは、
「そのとき読み込めた分をbufに上書きする」
だけで
「読み込めた分をbufの後ろに継ぎ足していく」
わけじゃありません
ので、別にバッファを用意して
recvが成功のたびに、そっちのバッファに継ぎ足していく必要があります
recv()についてはrinさんの指摘通りです。
継ぎ足していく場所の指定にrecv()の戻り値使います。
# 第3引数の値で移動させていって受信データ欠落させたことがあります(x_x)
あとは…recv()が0を返却した場合についても考慮した方がよろしいかと。
いろいろ試してはみたのですが、どうもうまくいきません。
軽い参考程度で構いませんのでできればソースをお願いしたいです。
なんとか送ることに成功しました。
みなさま誠にありがとうございます。
ツイート | ![]() |