vb@rchiv
VB Classic
VB.NET
ADO.NET
VBA
C#
vb@rchiv Offline-Reader - exklusiv auf der vb@rchiv CD Vol.4  
 vb@rchiv Quick-Search: Suche startenErweiterte Suche starten   Impressum  | Datenschutz  | vb@rchiv CD Vol.6  | Shop Copyright ©2000-2024
 
zurück
Rubrik: HTML/Internet/Netzwerk · Winsock   |   VB-Versionen: VB619.07.04
Dateien binär über das Winsock-Control senden und empfangen

Mit diesem Tipp ist es möglich, komplette Dateien binär über das Winsock-Control zu senden und zu empfangen.

Autor:   Dieter OtterBewertung:     [ Jetzt bewerten ]Views:  35.942 
www.tools4vb.deSystem:  Win9x, WinNT, Win2k, WinXP, Win7, Win8, Win10, Win11 Beispielprojekt auf CD 

Für den Datenaustausch zwischen zwei Rechnern wird i.a.R. das Winsock-Control verwendet. Einzelne kurze Texte lassen sich hiermit auch sehr einfach senden und empfangen. Oftmals möchte man aber komplette Dateien, z.B. Bilder, Datenbank-Dateien, etc. versenden. Und genau hier beginnen die Schwierigkeiten. Wie kann man große Daten ohne Datenverlust senden?

Die Lösung lautet: blockweise senden

Was ist damit genau gemeint? Hiermit ist gemeint, dass man die Dateien blockweise ausliest und demzufolge auch blockweise über das Winsock-Control versendet. Und damit die Gegenstelle, die die Daten empfängt, weiß, wieviele Daten insgesamt gesendet werden, sollte man zu Beginn des Sendevorgangs die Anzahl der zu sendenden Bytes übermitteln, und evtl. auch gleich noch den Dateinamen . Dies hat den Vorteil, dass die Gegenstelle sowohl den Empfangsfortschritt anzeigen und den Vorgang sofort beenden kann, wenn alle Daten angekommen sind - ohne auf irgendwelche Timesouts zu warten.

Beginnen wir mit dem Sendevorgang: Beim Senden einer Datei wird die Dateigröße und der Dateiname in folgendem Format an die Gegenstelle gesendet:

<begin size=#####;filename>

Die Datei wird natürlich im Binary-Mode geöffnet, so dass beim Auslesen der Daten keine Datenverluste entstsehen. Der Vesrand der Daten erfolgt in Blöcken von 1024 Bytes, und zwar so lange, bis alle Daten ausgelesen und versandt wurden.

Public Sub WinsockSendBinaryFile(ByVal sFile As String)
  Dim F As Integer
  Dim sBuffer As String
  Dim nFileSize As Long
  Dim nFilePos As Long
  Dim nBytesToRead As Long
 
  ' Größe der einzelnen Datenpakete
  Const BlockSize = 1024
 
  ' Datei im Binary-Mode öffnen
  F = FreeFile
  Open sFile For Binary As #F
 
  ' Dateiname extrahieren
  If InStr(sFile, "\") > 0 Then
    sFile = Mid$(sFile, InStrRev(sFile, "\") + 1)
  End If
 
  ' Dateigröße
  nFileSize = LOF(F)
 
  ' Sendevorgang starten
  With Winsock1
    ' Empfänger mitteln, welche Datei und wieviele
    ' Daten gesendet werden
    .SendData "<begin size=" & CStr(nFileSize) & ";" & sFile & ">"
 
    ' Datei blockweise senden
    Do While nFilePos < nFileSize
      nBytesToRead = BlockSize
      If nFilePos + nBytesToRead > nFileSize Then
        nBytesToRead = nFileSize - nFilePos
      End If
 
      ' Datenblock lesen
      sBuffer = Space$(nBytesToRead)
      Get #F, , sBuffer
 
      ' Datenblock senden
      .SendData sBuffer
 
      ' Fortschritt aktualisieren
      nFilePos = nFilePos + nBytesToRead
      txtStatusSend.Text = CStr(nFilePos) + " von " + CStr(nFileSize) + " Bytes versandt"
 
      ' Wichtig!
      DoEvents
    Loop
  End With
 
  ' Datei schließen (Sendevorgang beendet)
  Close #F
End Sub

Kommen wir nun zur Gegenstelle - dem Rechner, der die Daten empfangen soll.

Immer wenn Daten gesendet werden, wird hier das DataArrival-Ereignis ausgelöst. Die Daten selbst erhält man über die GetData-Methode. Als Erstes muss geprüft werden, ob eine neue Datei gesandt wird, indem die ersten 12 Bytes auf die vereinbarte Zeichenfolge <begin size= hin geprüft wird. Beginnt der String mit dieser Zeichenfolge, lesen wir aus dem String die Dateigröße, als auch den Dateinamen aus und öffnen die Datei ebenfalls im Binary-Mode.

Enthält der empfangene String nicht die vereinbarte Zeichenfolge, handelt es sich um die Daten, die dann in die zuvor geöffnete Datei gespeichert werden. Gleichzeitig können wir hier den Empfangs-Fortschritt mitführen und die Datei schließen, sobald alle Daten empfangen wurden.

' Wenn Daten ankommen...
Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long)
  Dim sData As String
  Dim sTemp As String
  Static sFile As String
 
  ' Daten holen
  Winsock1.GetData sData, vbString
 
  If Left$(sData, 12) = "<begin size=" Then
    ' Aha... eine neue Datei wird gesendet
    sData = Mid$(sData, 13)
    sTemp = Left$(sData, InStr(sData, ">") - 1)
    sData = Mid$(sData, InStr(sData, ">") + 1)
 
    ' Dateigröße und Dateiname ermitteln
    If InStr(sTemp, ";") > 0 Then
      nBytesTotal = Val(Left$(sTemp, InStr(sTemp, ";") - 1))
      sFile = Mid$(sTemp, InStr(sTemp, ";") + 1)
    Else
      nBytesTotal = Val(sTemp)
    End If
 
    ' Falls kein Dateiname angegeben wurde,
    ' Daten unter "temp.dat" speichern
    If Len(sFile) = 0 Then sFile = "temp.dat"
 
    ' ggf. Datei löschen, falls bereits existiert
    On Error Resume Next
    Kill App.Path & "\" & sFile
    On Error GoTo 0
 
    ' Datei im Binary-Mode öffnen
    nFile = FreeFile
    Open App.Path & "\" & sFile For Binary As #nFile
 
    ' bisher gelesene Bytes zurücksetzen
    nBytesRead = 0
  End If
 
  If Len(sData) > 0 And nFile > 0 Then
    ' bisher empfangene Daten...
    nBytesRead = nBytesRead + Len(sData)
 
    ' Daten in Datei speichern
    Put #nFile, , sData
 
    ' evtl. Fortschritt anzeigen
    txtStatusRecieve.Text = CStr(nBytesRead) & " von " & CStr(nBytesTotal) & " Bytes empfangen"
 
    ' Wenn alle Bytes empfangen wurden, Datei schließen
    If nBytesRead = nBytesTotal Then
      Close #nFile
      nFile = 0
    End If
  End If
End Sub

Ein kleines Anwendungsbeispiel:
Erstellen Sie ein neues Projekt und aktivieren im Komponenten-Dialog den Eintrag Microsoft Winsock-Control. Platzieren Sie das Winsock-Control auf die Form. Zusätzlich benötigen wir noch einen CommandButton (cmdSend) und zwei TextBox-Controls (txtStatusSend und txtStatusRecieve). Als Protokoll wählen wir das UDP-Protokoll, damit wir innerhalb des Projekts sowohl als senden, als auch Daten empfangen können.

Fügen Sie obigen Code in den Codeteil der Form ein. Im Form_Load Ereignis wird das Protokoll eingestellt. Als Port verwenden wir den Port 12345:

Option Explicit
 
' für den Empfangsvorgang
Dim nBytesTotal As Long
Dim nBytesRead As Long
Dim nFile As Integer
Private Sub Form_Load()
  ' UDP-Protokoll
  With Winsock1
    .Protocol = sckUDPProtocol
    .Bind 12345, .LocalIP
  End With
End Sub

Beim Klick auf den Sendebutton soll eine Bilddatei verschickt werden (D:\BILD1.JPG).

Private Sub cmdSend_Click()
  With Winsock1
    ' Port, an der die Daten gesendet werden
    .RemotePort = 12345
 
    ' Empfänger
    .RemoteHost = .LocalIP
  End With
 
  ' Bild-Datei senden
  WinsockSendBinaryFile "D:\BILD1.JPG"
End Sub

Ergänzen wir nun noch die DataArrival-Prozedur und zeigen das Bild sofort an, sobald dieses vollständig empfangen wurde:

' Wenn Daten ankommen...
Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long)
  ...
 
    ' Wenn alle Bytes empfangen wurden, Datei schließen
    If nBytesRead = nBytesTotal Then
      Close #nFile
      nFile = 0
 
      ' Bild anzeigen
      Image1.Picture = LoadPicture(App.Path & "\" & sFile)
    End If
  End If
End Sub

Das war's dann auch schon.
 

Dieser Tipp wurde bereits 35.942 mal aufgerufen.

Voriger Tipp   |   Zufälliger Tipp   |   Nächster Tipp

Über diesen Tipp im Forum diskutieren
Haben Sie Fragen oder Anregungen zu diesem Tipp, können Sie gerne mit anderen darüber in unserem Forum diskutieren.

Aktuelle Diskussion anzeigen (1 Beitrag)

nach obenzurück


Anzeige

Kauftipp Unser Dauerbrenner!Diesen und auch alle anderen Tipps & Tricks finden Sie auch auf unserer aktuellen vb@rchiv  Vol.6
(einschl. Beispielprojekt!)

Ein absolutes Muss - Geballtes Wissen aus mehr als 8 Jahren vb@rchiv!
- nahezu alle Tipps & Tricks und Workshops mit Beispielprojekten
- Symbol-Galerie mit mehr als 3.200 Icons im modernen Look
Weitere Infos - 4 Entwickler-Vollversionen (u.a. sevFTP für .NET), Online-Update-Funktion u.v.m.
 
   

Druckansicht Druckansicht Copyright ©2000-2024 vb@rchiv Dieter Otter
Alle Rechte vorbehalten.
Microsoft, Windows und Visual Basic sind entweder eingetragene Marken oder Marken der Microsoft Corporation in den USA und/oder anderen Ländern. Weitere auf dieser Homepage aufgeführten Produkt- und Firmennamen können geschützte Marken ihrer jeweiligen Inhaber sein.

Diese Seiten wurden optimiert für eine Bildschirmauflösung von mind. 1280x1024 Pixel