Visual Basic Forum

Visual Basic Forum
für VB6 und VB.NET Programmierer
 
RegistrierenRegistrieren  LoginLogin

Neues Thema eröffnen   Neue Antwort erstellen    Visual Basic Forum Foren-Übersicht -> [VB6] Texte und Ebooks
Autor
Nachricht
ZiG_
Überflieger
Überflieger

Anmeldedatum: 07.03.2007
Beiträge: 1248

[Text] Winsock File Transfer
Verfasst am: 08.08.2007, 16:36

Thema: Winsock Datentransfer

1. Einleitung
2. Client - Dateiversand
3. Server - Dateiempfang
4. Fazit


1. Einleitung
Nach dem Tutorial über das Winsock Array möchte ich euch in diesem Tutorial noch zeigen wie einfach es ist eine Datei per Winsock zu versenden.
Viele sources die verbreitet werden sind entweder schwer zu verstehen oder nutzen die Technik jedes Byte einzeln zu versenden, was natürlich enorme Zeit braucht bei größeren Dateien.
Ich werde euch eine viel einfachere Technik an einem simplen Beispiel zeigen, die ich benutze.

Benötigen werdet ihr:
Beim Client:
1. 1x Common Dialog Control (Im Code als „cdlg“ abgekürzt)
2. 1x Button (Command1)
3. 1x Winsock Control (ws)
4. 1x Label (Label1)
Beim Server:
1. 1x Button (Command1)
2. 2x Label (Label1 und Label2)
3. 1x Winsock Control (ws)

2. Client - Dateiversand
Den Client werden wir so coden, dass er für den Dateiversand zuständig ist.
Damit wir überhaupt mal Verbindungen entgegen nehmen können müssen wir das Winsock Control auf Listen setzen.
Code:

Private Sub Form_Load()
ws.LocalPort = 2222
ws.Listen
End Sub


Und eingehende Verbindungen akzeptieren wir hiermit.
Code:

Private Sub ws_ConnectionRequest(ByVal requestID As Long)
ws.Close
ws.Accept requestID
Label1.Caption = "Connection established"
End Sub


Damit wir auch sehen ob eine Verbindung besteht, wird gleich in Label1 eine Message ausgegeben.
Das selbe wenn eine Verbindung geschlossen wird.
Code:

Private Sub ws_Close()
Label1.Caption = "Connection lost"
End Sub


Das waren jetzt mal so die Standard Sachen für eine simple Winsock Verbindung.
Jetzt benutzen wir noch das Common Dialog Control im Button, damit ihr später einfach eine Datei aussuchen könnt.
Code:

Private Sub Command1_Click()
On Error GoTo Err:

With cdlg
 .CancelError = True
 .ShowOpen
 If SendFile(.FileName) Then GoTo Err:
End With

Exit Sub
Err:
Call MsgBox("Error while sending the file!", vbCritical)
End Sub


Bis jetzt sollte eigentlich alles ohne Erklärungen klar sein. Ansonsten solltet ihr euch vorher andere Tuts ansehen, die euch mehr Basiswissen übers Winsock vermitteln.

Und jetzt kommen wir zum eigentlichen code. Jetzt kümmern wir uns um die Funktion Sendfile, die in Command1 aufgerufen wird.

Code:

Private Function SendFile(ByVal Filepath As String) As Boolean
'Hier wird die Datei versendet
Dim buffer As String, pos As Long, bytes As Long, AllComplete As Boolean

pos = 1
bytes = 65535
AllComplete = False
SendComplete = False

'Datei öffnen
Open Filepath For Binary As #1

'Die Schleife läuft so lange, bis die Datei versendet wurde
Do
 If (LOF(1) - pos) > bytes Then
  'Teil der Datei einlesen
  buffer = Space(bytes)
  Get #1, pos, buffer
  pos = pos + bytes
 Else
  bytes = (LOF(1) - pos) + 1
  buffer = Space(bytes)
  Get #1, pos, buffer
  AllComplete = True
 End If
 
 'Daten senden
 ws.SendData (buffer)
 buffer = ""
 
 'Warten bis der Teil gesendet wurde
 Do
  DoEvents
 Loop Until SendComplete
Loop Until AllComplete

Close
Call MsgBox("Sending complete")

End Function


Erklärung zur Funktion
Im Grunde ist es sehr einfach.
Der Code funktioniert so, dass er die Datei Stückchenweise einliest und versendet.
Da das Winsock Control immer nur eine gewisse Menge an Bytes auf einmal versenden kann (65535Bytes max), können wir auch nicht größere Stücke auslesen.

Hier mal die wichtigsten Variablen:
pos zeigt immer unsere letze Position in der Datei an. Mit 1 fangen wir natürlich an.
bytes übergibt die Anzahl an Bytes, die immer ausgelesen werden sollen.
AllComplete ist True, wenn die komplette Datei versendet wurde.
SendComplete ist True, wenn ein Teil der Datei versendet wurde.
Filepath ist natürlich der Pfad zur Datei, die gesendet werden soll.
buffer ist der Zwischenspeicher für unsere Teile der Datei.

Und jetzt erkläre ich noch die wichtigen Zeilen.
Code:

If (LOF(1) - pos) > bytes Then

Diese If Abfrage überprüft ob die noch zu auslesenden Bytes mehr sind, als in bytes drinnen steht.
Wozu? Ganz einfach.
Wir wollen immer 65535Bytes auslesen. Wenn wir aber ans Ende der Datei kommen und nur noch z.B. 821Bytes zum auslesen sind, würden wir beim einlesen aus der Datei Blödsinn erhalten oder sogar einen Fehler.
Und wenn also weniger als 65535Bytes übrig sind zum auslesen, dann wird die Anzahl der restlichen Bytes an die Variable bytes übergeben.
Code:

bytes = (LOF(1) - pos) + 1



Und hier die Erklärung zum einlesen der Datei:
Code:

  buffer = Space(bytes)
  Get #1, pos, buffer
  pos = pos + bytes

Wir benutzen eine string Variable und nicht eine byte, so wie in vielen anderen sources.
Mit Get können wir unseren Teil einlesen. Aber man kann nur sagen, von wo er zum einlesen anfangen soll. Natürlich von pos.
Aber man kann nicht angeben, wie viel er einlesen soll.
Deshalb füllen wir die Variable buffer vorher mit sovielen Leerzeichen wie in bytes drinnen steht.
Stellt euch den string am besten wie eine leere Flasche vor, die sich bis zum Rand füllt wenn ihr sie unters Wasser haltet. Mehr passt einfach nicht rein.
Wenn wir also buffer mit genau 65535 Leerzeichen füllen, passt auch nicht mehr hinein.

Und in der Zeile „pos = pos + bytes“ wird einfach die letze Position aktualisiert, damit wir beim einlesen des nächsten Teiles wissen wo wir zuletzt waren.

Und jetzt kommt noch etwas sehr wichtiges.
Code:

Do
  DoEvents
 Loop Until SendComplete

Ich weiß. Sieht nicht wichtig aus, ist es aber.
Diese Schleife läuft solange, bis die Boolean Variable SendComplete True ist.
Diese Variable müsst ihr Global deklarieren.
Und dann müssen wir sie noch in die Sub ws_SendComplete() einfügen.
Code:

Private Sub ws_SendComplete()
SendComplete = True
End Sub

Wenn ein Teil versendet wurde, wird diese Sub ausgelöst und unsere Variable auf True gesetzt.
Und das war es auch schon mit dem Klienten.


3. Server - Dateiempfang

Hier mal die Grundlegenden Sachen.
Code:

Private Sub Command1_Click()
ws.Connect "127.0.0.1", 2222
End Sub

Private Sub ws_Close()
Label1.Caption = "Connection lost"
End Sub

Private Sub ws_Connect()
Label1.Caption = "Connection established"
End Sub


Und hier die Sub zum empfangen der Datei.
Code:

Private Sub ws_DataArrival(ByVal bytesTotal As Long)
Dim buffer As String

ws.GetData buffer
Open (App.Path & "\test.exe") For Binary As #1
Put #1, LOF(1) + 1, buffer
buffer = ""
Close

End Sub

In buffer empfangen wir die einzelnen Teile.
Und mit Put #1, LOF(1) +1, buffer schreiben wir jeden Teil ans Ende der Datei.
Zur Sicherheit leeren wir dann noch die Variable buffer

4. Fazit
Wie ihr seht ist es also gar nicht so schwer. Wink
Natürlich ist das Beispiel sehr simple. Aber ich hoffe, dass ich euch ein wenig die Funktionsweise eines Datentransfers vermitteln konnte.

Hier habe ich auch noch den Beispielsource als Download für euch.
Download: Link
pw: vb-x.org

mfg, ZiG
_________________


Zuletzt bearbeitet von ZiG_ am 15.11.2007, 17:32, insgesamt einmal bearbeitet
 
Hamtaro_
« Moderator »<b><font color=green>« Moderator »</font



Anmeldedatum: 06.05.2007
Beiträge: 217
Wohnort: NRW


Verfasst am: 09.08.2007, 06:32

Und wieder mal einen Heftigen Applaus für: ZiG :respekt: Exclamation
das ist ja mal ein Beispiel, dass bestimmt vielen helfen wird.
Und dazu noch sehr gut erklärt.
Wenn ich einen Hut aufhätte zöge ich ihn jetzt vor dir, da ich aber keinen habe, lasse ich ihn auf...
Trotzdem Weiter So, ZiG!
_________________
Wie findet ihr meine Sig?
 
r4z3r_
« Webmaster »<b><font color=red>« Webmaster »</fo



Anmeldedatum: 06.02.2007
Beiträge: 252


Verfasst am: 09.08.2007, 11:42

wie kannst du einen hut auflassen den du nicht hast?^^

naja wieder ein tolles tut Cool

*auch applaudir* :biggthumpup:
 
Archetype_
Newbie
Newbie

Anmeldedatum: 30.08.2007
Beiträge: 8


Verfasst am: 30.08.2007, 14:23

Soweit ich das sehe wird die funktion sendfile in einer endlosschleife stecken bleiben , da sendcomplete nie auf true gesetzt wird (im gegensatz zu allcomplete ) .
vielleicht stell ich mich auch nur dumm an , bei mir gehts jedenfalls nicht , die funktion hängt sich auf und die übertragenen dateien sind 0 kb groß .
wäre dir aber trotzdem dankbar wenn du zurückposten würdest , sieht generell sehr brauchbar aus

Code:

Do
  DoEvents
Loop Until SendComplete
 
The-God-of-all_
Poster
Poster

Anmeldedatum: 20.05.2007
Beiträge: 170
Wohnort: App.Path


Verfasst am: 30.08.2007, 15:34

Archetype hat Folgendes geschrieben:
Soweit ich das sehe wird die funktion sendfile in einer endlosschleife stecken bleiben , da sendcomplete nie auf true gesetzt wird (im gegensatz zu allcomplete ) .
vielleicht stell ich mich auch nur dumm an , bei mir gehts jedenfalls nicht , die funktion hängt sich auf und die übertragenen dateien sind 0 kb groß .
wäre dir aber trotzdem dankbar wenn du zurückposten würdest , sieht generell sehr brauchbar aus

Code:

Do
  DoEvents
Loop Until SendComplete



Hast du auch das:
[vb:1:0323a20b93]Private Sub ws_SendComplete()
SendComplete = True
End Sub[/vb:1:0323a20b93]
eingefügt? weil ZiG hat ja erklärt das diese Schleife dazu da ist dass das Programm wartet bis die Daten fertig gesendet wurden, und das wird in der Variable SendComplete gespeichert, sie wird mit der oben geposteten Sub auf True gesetzt wenn die Daten fertig gesendet sind.
 
Archetype_
Newbie
Newbie

Anmeldedatum: 30.08.2007
Beiträge: 8


Verfasst am: 30.08.2007, 18:22

ok ich war blind
danke

nochwas , aus irgendeinem Grund sind bei mir übertragenen Daten nie größer als 8 kb und somit meist fehlerhaft .

kann mir jemand erklären warum ?


Edit : auch das hat sich egrade geklärt , ist heute anscheinend nicht so mein tag ^^
 
Crypt0r_
Newbie
Newbie

Anmeldedatum: 02.09.2007
Beiträge: 6


Verfasst am: 21.11.2007, 18:51

diese Zeile verstehe ich überhaupt nicht:

Code:
 If SendFile(.FileName) Then GoTo Err:


Wozu ist die da?
 
ZiG_
Überflieger
Überflieger

Anmeldedatum: 07.03.2007
Beiträge: 1248


Verfasst am: 21.11.2007, 19:23

Hmm, kann ich nicht mehr genau sagen was ich mir bei dem Aufruf gedacht habe.
Jedenfalls wird die Funktion SendFile aufgerufen und der Dateipfad übergeben.
Da SendFile Als Boolean deklariert ist, könnte sie wenn man es so programmiert entweder True oder False zurückgeben.

Ich hab das scheinbar vergessen und wenn man es genau will sollte es evt. so heißen.
Code:

 If Not SendFile(.FileName) Then GoTo Err:


Und in der Funktion Sendfile dann einfach True wenn es geklappt hat zurückgeben. Ansonsten False.
Oder das ganze überhaupt einfach weglassen.
_________________
Wer nicht auf seine Weise denkt, denkt überhaupt nicht. (Oscar Wilde)
 
DimaMa_
Newbie
Newbie

Anmeldedatum: 12.04.2008
Beiträge: 4

Probleme mit Winsock!
Verfasst am: 23.04.2008, 19:05

Ich habe brobleme mit meiner sinconsole .
der server öffnet das test.exe aber schreibt iwie nichts rein (alles versucht 2 winsockets,2ports) hoffnungslos bitte helft mal .
 
ZiG_
Überflieger
Überflieger

Anmeldedatum: 07.03.2007
Beiträge: 1248


Verfasst am: 23.04.2008, 19:09

Erstell bitte dazu einen Thread in "Fragen und Antworten"
_________________
Wer nicht auf seine Weise denkt, denkt überhaupt nicht. (Oscar Wilde)
 
DimaMa_
Newbie
Newbie

Anmeldedatum: 12.04.2008
Beiträge: 4

Bei mir kommet ein fehler
Verfasst am: 24.04.2008, 18:07

Bei mir kommt ein Fehler ZiG nachdem ich das einfüge:
Private Sub Winsock1_SendComplete()
SendComplete = True
End Sub

_________________


 
ZiG_
Überflieger
Überflieger

Anmeldedatum: 07.03.2007
Beiträge: 1248


Verfasst am: 24.04.2008, 18:42


Dann hast du den selben Event wahrscheinlich schonmal erstellt.
Und wie gesagt. Erstell zu Fragen bitte einen Thread in "Fragen und Antworten"!
_________________
Wer nicht auf seine Weise denkt, denkt überhaupt nicht. (Oscar Wilde)
 
Neues Thema eröffnen   Neue Antwort erstellen    Visual Basic Forum Foren-Übersicht -> [VB6] Texte und Ebooks

Tags: winsock datentransfer, file, transfer

 
 Verwandte Themen   Aufrufe   Letzter Beitrag 
Keine neuen Beiträge Visual Basic Download ? 1741 03.05.2011, 07:38
Keine neuen Beiträge Api Download in Prozent + Kb anzeige + Progrezzbar 1345 21.10.2007, 13:03
Keine neuen Beiträge Download 1358 30.08.2007, 15:45
Keine neuen Beiträge Download mit Internet Explorer Object 923 18.08.2008, 19:00
Keine neuen Beiträge Visual Basic 6 download 3699 26.05.2007, 11:51
 



[ Time: 0.4263s ][ Queries: 125 (0.0314s) ][ GZIP on - Debug on ]