Hallo Hendrik,
leider schon mein zweites Problem in zwei Tagen.
Es handelt sich um einen Filetransfer.
Von dem ersten habe ich leider nichts mitbekommen. Hast du es gelöst oder sind noch Fragen offen?
Wenn ich auf meinem Rechner das Programm zweimal starte und
eine 4 MB Datei „versende“, dann dauert das ganze 30 Minuten.
Was verstehst du unter 2 mal?
2 mal hintereinander und 2 mal zur gleichen Zeit?
Aber 30 Minuten für 4 MB ist schon heftig!!
Was für eine Abindung haben denn beide Anschlüsse? ( DSL xxx ?)
Wie ist die Up sowie Download Geschwindigkeit beider Rechner?
Das Programm hängt aber nicht in irgendwelchen Schleifen,
sondern bleibt bei der Ausführung über eine Sekunde bei
„Winsock.SendData“ hängen.
Sendest du die Daten im Internet oder übers LAN?
Ich habe absolut keine Ahnung,
warum das so lange dauert.
Na schauen wir einmal!
Sind 1024 Byte als Block etwa zu groß?
Nein die kann man noch höher setzen!
Ich poste zum besseren Verständis mal den Code:
'Gilt für beide
Const Block = 1024
'Beim Sender
Private strFile As String
Private Sub sendfile()
Dim sData As String
Dim intDateiNr As Integer
intDateiNr = FreeFile
Open strFile For Binary Access Read As #intdateinr
Do While Not EOF(intdateinr)
sData = Input(Block, #intdateinr)
wsckFile.SendData sData
DoEvents
Loop
Close #intdateinr
End Sub
Warum so umstaendlich?
Was ist wenn ein ungültiger Wert gelesen wird?
Warum das DoEvents?
'Beim Empfänger
Private pos As Long
Private strFile As String
Private Sub wsckfile_DataArrival(ByVal bytesTotal As Long)
Dim BlocksCount As Integer
Dim intNewFile As Integer
Dim Data As String
BlocksCount = bytesTotal / Block
If pos = 0 Then
pos = 1
End If
wsckFile.GetData Data
intNewFile = FreeFile
For i = 1 To BlocksCount
Open strFile For Binary Access Write As #intNewFile
Seek #intNewFile, pos
Put #intNewFile, , Left(Data, Block)
Close #intNewFile
pos = pos + Block
If Len(Data) > Block then
Data = Mid(Data, Block + 1)
End if
Next i
End Sub
Hier hast du aber maechtige Böcke drinnen.
Schauen wir uns das mal genauer an.
Wir senden mal 4 MB! Das bedeutet 4*1024*1024=4194304 Bytes!
Bei einer Blockgrösse von 1024 waeren das 4194304 / 1024 = 4096 Sendevorgaenge! Das diese eine Weile dauern ist ganz normal!
Aber schauen wir uns mal deine Routine an!
If pos = 0 Then
pos = 1
End If
Wieso das?
> wsckFile.GetData Data
Nicht gut!!! Gesetz dem Fall du sendest schneller als du empfängst so hast du streckenweise mehr wie die Blockgrösse an Daten! Es könnten bsp.weise mal 1512 Byte’s anliegen! Entweder du sendest ein Trennzeichen mit oder wenn du die Blockgrösse weisst dann kannst du auch die Daten einlesen. Aber woher soll der Client das wissen?
Soll die Routine nicht flexibel werden?
intNewFile = FreeFile
'Das ist OK
For i = 1 To BlocksCount
'Wo ist I Declariert?
'Selbst und wenn gesetz dem Falle Blocksize = 1024 und es liegen mal
'1513 Bytes an. Du hast eine Schrittweite von 1 Aber 1512 / 1024 ist '1,477 ...
'Das bedeutet du würdest zwar die ersten 1024 Bytes schreiben, aber 'die restlichen verwerfen!
Open strFile For Binary Access Write As #intNewFile
Das ist OK!
Seek #intNewFile, pos
Ok, umstaendlich, aber Ok!
Put #intNewFile, , Left(Data, Block)
Was ist wenn Data \> Block ist. Dann verwirfst du die Daten!
Put #intNewFile, , Left(Data, Block)
Ja ok, das passt
> Close #intNewFile
Das auch, aber warum jedesmal die Datei öffnen und schliessen?
pos = pos + Block
Auch das kann man einfacher machen :s
If Len(Data) \> Block then
Data = Mid(Data, Block + 1)
End if
Hier hast du den naechsten Bock drinnen!
Nehmen wir mal an du bekommst 1027 Bytes gesendet!
Die letzten 3 byte sind ABC.
Hier würdest du unter DATA ABC speichern.
Nun kommen aber die naechsten 1513 Bytes an.
Durch die Anweisung "wsckFile.GetData Data" verwirfst du den Inhalt von Data. Sprich das ABC und die Daten sind verloren!
Next i
Ja ok, das passt
Desweiteren prüfst du nicht ob genuegend Speicherplatz vorhanden ist.
OB das File schon existiert
Ob eine Verbindung zwischen den beiden Rechner besteht. Das sollte man vor JEDEM senden prüfen!
und und und.
Wie du nun siehst ist deine Routine sehr störanfaellig und fehlerhaft.
Du solltest dir dein Konzept nochmals ueberlegen.
Ein kleiner Tipp, um dein Ziel naeher zu kommen!
'Server
Vor jedem senden prüfen ob eine Verbindung besteht!
Beim senden.
Senden im Format [000000]DeineDaten
'Für die 0 setzt du von Rechts her die grösse der Daten ein die du sendest. Das hat den Vorteil das du flexibel bist!
'Du weisst das die ersten 8 Zeichen unrelevant sind.
'Bsp [000005]Start
Vor dem ersten senden, sendest du dem Clienten das es sich um ein Filehandling handelt.
'Dann sendest du die FileSize, danach den Filenamen und dann das der Transfer beginnt. Du kannst das natuerlich auch in eins senden.
'Bsp:[000025]C:\Test.txt;412345676354
'Dein Client weiss nun den Dateinamen und die Datenmenge!Anhand des ; kannst du die Daten trennen.
' Nach senden der Daten, lässt du den Server auf eine Bestaetigung
'vom Clienten warten und danach sendest du die Daten in einer
'Schleife in der Form [000000]Deine Daten
'Nach jeden Senden wartest du auf eine Bestaetigung!
'Nachdem alle Daten gesendet sind, sagst du das dem Clienten in der Form
'[000003]End
'Warten auf Bestatigung und schliessen des Connectes vom Clienten
'Client
'Beim Empfang, prüfen ob die Datei existiert: Je nachdem agieren
'FileSize und Dateinamen ermitteln
'Speicherplatz überprüfen
'Variable als Zeichenfolge declarieren und als STATIC
'Server eine Bestaetigung senden
'Wenn Datenempfang kommt, Dann die Daten in einer zweiten Variable die auch als Static declariert ist speichern. Überprüfen ob die Anzahl der Zeichen stimmen! Wenn die Daten
Das ist nur ein Weg von vielen und soll dir als Anstoss dienen. Das zu relaisieren ist rel. simple :smile:
MfG Alex
> Vielen Dank im Vorraus.
>
> MfG Hendrik Hilleckes