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: 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 36.281 mal aufgerufen. Voriger Tipp | Zufälliger Tipp | Nächster Tipp
Anzeige
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. |
Neu! sevCoolbar 3.0 Professionelle Toolbars im modernen Design! Mit sevCoolbar erstellen Sie in wenigen Minuten ansprechende und moderne Toolbars und passen diese optimal an das Layout Ihrer Anwendung an (inkl. große Symbolbibliothek) - für VB und MS-Access Tipp des Monats Dezemeber 2024 Roland Wutzke MultiSort im ListView-Control Dieses Beispiel zeigt, wie sich verschiedene Sortierfunktionen für ein ListView Control realisieren lassen. TOP Entwickler-Paket TOP-Preis!! Mit der Developer CD erhalten Sie insgesamt 24 Entwickler- komponenten und Windows-DLLs. Die Einzelkomponenten haben einen Gesamtwert von 1605.50 EUR... |
||||||||||||||||
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. |