バイナリファイル通信について

解決


ふらいぱん  2005-02-05 11:32:47  No: 88253

今現在、Winsockでのキャプチャ画像送受信プログラムをせっせと作ってます。
そこで1つ目の壁に当たりました・・・。
Winsockでの文字列送受信は難なくカキカキできるのですが、バイナリデータの送受信方法がわかりませんorz

とりあえず過去ログをほじくっていろいろ試してみたのですが、
環境が違うせいか「Indexが有効範囲ではありません。」
というエラーや
「データグラムが大きいためバッファが切り詰められます。」
というエラーが発生しました。

問題個所は以下です。

#送信側
Dim send() As Byte
Dim FileNumber As Integer

FileNumber = FreeFile()
Open "tes.jpg" For Binary Access Read As FileNumber
ReDim send(0 To LOF(FileNumber) - 1) 'ここでエラリますorz
Get FileNumber, , send()
Close filenumber
    Winsock1.SendData send
-------------------------------------------------------
#受信側
Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long)
    Dim RecvData() As Byte
    Winsock1.GetData RecvData, vbArray + vbByte, bytesTotal

Dim GetFileByte() As Byte
Dim FileNumber As Integer

FileNumber = FreeFile()
Open "tes2.jpg" For Binary As FileNumber
ReDim GetFileByte(0 to LOF(FileNumber) - 1) '同じくエラりますorz
Get FileNumber, , GetFileByte()
Close FileNumber

End Sub

もう助けてください('A`)
通信方法はUDPです。(何故かってのは聞かないでください。ヘコミます)

環境:Windows98SE VB6


真夜中のVBer  2005-02-05 13:04:56  No: 88254

>ReDim send(0 To LOF(FileNumber) - 1) 'ここでエラリますorz
何のエラーが発生しているんでしょう?
「Indexが有効範囲ではありません」ですか?
この行の前に
Debug.Print LOF(FileNumber)
として取得した長さを表示させてみてください。

あと、受信側の
>FileNumber = FreeFile()
>Open "tes2.jpg" For Binary As FileNumber
>ReDim GetFileByte(0 to LOF(FileNumber) - 1) '同じくエラりますorz
>Get FileNumber, , GetFileByte()
>Close FileNumber
これは何やってるんですか?
受信したデータを書き出すなら

Open "tes2.jpg" For Binary As FileNumber
Put FileNumber,,RecvData
Close FileNumber

じゃないんですか?
大きいファイルだと複数回DataArrivalが発生するだろうから
OpenとCloseは別のタイミングでした方がいいかも。

処理が遅くなってもいいなら
Open "tes2.jpg" For Binary As FileNumber
Seek FileNumber,LOF(FileNumber)+1
Put FileNumber,,RecvData
Close FileNumber
でもいいけど。


真夜中のVBer  2005-02-05 14:25:47  No: 88255

ひとつへなちょこな例を。
フォームにCommand1とWinsock1とWinsock2を貼り付けて以下のコードを書く
Winsock1が送信側でWinsock2が受信側とした。
Command1をクリックして送信開始となる。

'----------------------------------- 送信側
Private Sub Command1_Click()

  Dim lngFileLen    As Long       'ファイルサイズ
  Dim lngSendBytes  As Long       '送信済みバイト数
  Dim intF          As Integer    'ファイル番号
  Dim lngPduSize    As Long       '送信パケットデータサイズ
  Dim bytSend()     As Byte       '送信バッファ
  
  Winsock1.RemoteHost = "127.0.0.1"  '適当なホスト
  Winsock1.RemotePort = 20000        '適当なリモートポート
  Winsock1.Bind 20001                '適当なバインドポート
  
  intF = FreeFile
  Open "適当なファイル名" For Binary As intF
  
  lngFileLen = LOF(intF)          'ファイルサイズの取得
  lngSendBytes = 0                '送信済みバイト数
  lngPduSize = 5000               '1回の送信バイト数をとりあえず5000にする
  ReDim bytSend(lngPduSize - 1)   '送信バッファのサイズをPDUのサイズにする
  
  Do While lngSendBytes < lngFileLen
    Debug.Print lngSendBytes, lngFileLen
    If lngFileLen - lngSendBytes < lngPduSize Then
      '最後の送信バッファのサイズを調整
      ReDim bytSend(lngFileLen - lngSendBytes - 1)
      lngSendBytes = lngFileLen
    Else
      '送信済みバイト数をカウントアップ
      lngSendBytes = lngSendBytes + lngPduSize
    End If
    Get intF, , bytSend         'ファイルより送信データを取得
    Winsock1.SendData bytSend   '送信
    DoEvents                    'システムに送信するタイミングを与える
  Loop
  Close intF
  
End Sub

'----------------------------------- 受信側
Private Sub Form_Load()

  Winsock2.RemoteHost = "127.0.0.1" '適当なホスト
  Winsock2.RemotePort = 20001       '適当なリモートポート
  Winsock2.Bind 20000               '適当なバインドポート

End Sub

Private Sub Winsock2_DataArrival(ByVal bytesTotal As Long)

  Dim RecvData()  As Byte
  Dim intF        As Integer
  
  Winsock2.GetData RecvData
  intF = FreeFile
  Open "適当なファイル名2" For Binary As intF
  Seek intF, LOF(intF) + 1
  Put intF, , RecvData
  Close intF

End Sub

ただ、これを実行してみたら分かると思うが、致命的な欠点がある。
送信側で続けて別のファイルを送信すると受信側でファイルが変わったかどうか
の判断ができないため延々と同じファイルに追記し続けることになる。

最初にファイルサイズを予め送信側から受信側に通知しておけば
受信側でファイルの終わりを検知することができるようになる。
そうすればSeekなんて作業もしなくてよくなるので処理も若干速くなるかも。

でもUPDはパケットの到着順序が保証されていないから結局もっとしっかりした
プロトコルを作って通信しないとだめかも。


ふらいぱん  2005-02-05 15:41:38  No: 88256

ホントもー感謝です。
おかげさまでモヤモヤが壊れました。
詳しいサンプルのっけてくれてどうもです。
連続送信させる場合は間を置くんで多分大丈夫だと思います。

真夜中にどうもでしたーノシ


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

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






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