音声ファイル転送

解決


ペンペン  2008-12-23 01:42:23  No: 69325

音楽ファイルを送ろうと現在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);
  
}

以上です。
送信側と受信側の両方で、デバッガを実行させながら比較するとうまく音声がなるのですが、普通にやると音が鳴りません。
どなたかアドバイスをお願いします。


subaru  2008-12-23 02:51:15  No: 69326

非同期再生なのに即座にプログラムを終了してしまってるということなら
PlaySoundの3番目の引数をSND_SYNCにすると同期再生になります。
関係なかったらスミマセン。


瀬戸っぷ  2008-12-23 10:24:04  No: 69327

send()で1回で送信したからといって、recv()でも1度で受信できるワケではない…のですが、その辺り大丈夫なんでしょうか?

最初にデータサイズを数字化して、512バイト送信しているようですが、
受信側の最初のrecvで20バイトしか受信していないかも知れません。
そうすると、次にrecv()したときにはまだ受信処理していない492バイトが残っています。


ペンペン  2008-12-24 21:11:33  No: 69328

subaruさん
非同期ではないのでおそらく関係はないと思います。
でもレス感謝です。

瀬戸っぷさん
つまりrecvを何度も繰り返せば解決ってことですね。
わざわざありがとうございます。


subaru  2008-12-24 22:23:27  No: 69329

>subaruさん
>非同期ではないのでおそらく関係はないと思います。
>でもレス感謝です。

ここで言う非同期とはソケットのことではなくPlaySoundの再生方法のことです。
PlaySoundが引数がSND_ASYNCの場合は非同期であるとMSDNに書いてあります。

>瀬戸っぷさん
>つまりrecvを何度も繰り返せば解決ってことですね。
>わざわざありがとうございます。

こちらが原因なら出来上がったファイル自体が不完全な状態になっている
のでデバッガを使わなくてもすぐ確認できるはずです。
shutdownもしてないし、どちらにしても送受信は見直す必要がありますが・・・


瀬戸っぷ  2008-12-25 08:26:28  No: 69330

>つまりrecvを何度も繰り返せば解決ってことですね。

基本的にはそうなりますが…
ブロッキングモードだと受け取るデータが無くなると受信するまで(あるいは切断されるまで)戻ってきませんので注意が必要です。
TCP/IP通信関係で検索すれば事例とかあるかと思われますが。
とりあえずrecv()の戻り値はしっかり確認しましょう。


ペンペン  2008-12-25 20:24:03  No: 69331

送信側を
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);
にしてみたのですが、結果は同じでした。
ほかにできればアドバスをお願いします。


rin  2008-12-25 21:20:13  No: 69332

>res = recv(m_sock1, buf, sizeof(buf), 0);
recvは、
「そのとき読み込めた分をbufに上書きする」
だけで
「読み込めた分をbufの後ろに継ぎ足していく」
わけじゃありません

ので、別にバッファを用意して
recvが成功のたびに、そっちのバッファに継ぎ足していく必要があります


瀬戸っぷ  2008-12-26 08:31:50  No: 69333

recv()についてはrinさんの指摘通りです。

継ぎ足していく場所の指定にrecv()の戻り値使います。
# 第3引数の値で移動させていって受信データ欠落させたことがあります(x_x)

あとは…recv()が0を返却した場合についても考慮した方がよろしいかと。


ペンペン  2009-01-05 23:43:10  No: 69334

いろいろ試してはみたのですが、どうもうまくいきません。
軽い参考程度で構いませんのでできればソースをお願いしたいです。


ペンペン  2009-01-07 01:28:02  No: 69335

なんとか送ることに成功しました。
みなさま誠にありがとうございます。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加