今現在、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
>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
でもいいけど。
ひとつへなちょこな例を。
フォームに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はパケットの到着順序が保証されていないから結局もっとしっかりした
プロトコルを作って通信しないとだめかも。
ホントもー感謝です。
おかげさまでモヤモヤが壊れました。
詳しいサンプルのっけてくれてどうもです。
連続送信させる場合は間を置くんで多分大丈夫だと思います。
真夜中にどうもでしたーノシ
ツイート | ![]() |