Datei Empfangen (Prozessor auslastung zu hoch)!

Für allgemeine Fragen zur Programmierung mit PureBasic.
Benutzeravatar
dige
Beiträge: 1237
Registriert: 08.09.2004 08:53

Beitrag von dige »

Hier mal eine Procedure zum Häppchenweisen Empfang von Daten,
die direkt in eine Datei geschrieben werden:

Code: Alles auswählen

; 07/02/2005 by dige, german forum
Procedure.b ReceiveNetworkFileEx ( ClientID.l, File.s )
  Protected buffer.l, FileNr.l, success.b
  
  FileNr = OpenFile( #PB_Any, File )
  buffer = 128
  *mem   = AllocateMemory( buffer )

  If FileNr
    Repeat
      Result = ReceiveNetworkData( ClientID, *mem, buffer ) 
      If Result > 0 : WriteData(*mem, Result) : EndIf
      Delay(1)
    Until Result < buffer
    
    CloseFile( FileNr )
    success = #True
  EndIf
  
  FreeMemory( *mem )
  ProcedureReturn success
EndProcedure
Deine Datei musst Du dann natürlich mit SendNetworkData() senden!

cya dige
Team100
Beiträge: 104
Registriert: 13.09.2004 22:59

Beitrag von Team100 »

@dige

ReceiveNetworkData kann folgende Ergebnisse liefern:

- die Anzahl der empfangenen Bytes, und diese stimmt mit
der gewünschten Länge (hier <buffer>) überein

- die Anzahl der empfangenen Bytes, diese ist jedoch kleiner
als die gewünschte Länge (es sind zwar schon Daten da vom
Netzwerk, aber eben noch nicht alle -- abhängig von Auslastung,
Geschwindigkeit etc)
Diesen Effekt bezeichne ich mal als Unterlänge.

- den Wert -1, es konnte nichts empfangen werden.

Das Codeschnippsel nimmt nun keine Rücksicht auf eine
mögliche Unterlänge, die bei <buffer = 128> in einem
lokalen unausgelasteten Netz selten auftreten wird, aber
doch irgendwann einmal. Bei buffer > 5000 ist das schon
anders, Unterlängen sind die Regel.

Im Falle einer Unterlänge wird die Repeat-Schleife verlassen
und der Rest wird dann dem nächsten Sendepaket vorangestellt.....
Eventuell ergibt sich ein gewisser Selbstheilungseffekt, wenn die
Procedur oft genug aufgerufen wird und so die Daten vom Netzwerk
abgeholt werden.... besser auf die Unterlänge reagieren und nur
mehr den Rest (oder wieder eine neue Unterlänge) abholen.

Wenn die Procedur zum sukzessiven Aufbau der Datei gedacht
ist, sollte auch noch ein Fileseek... nach dem Openfile hinein um ans
Dateiende zu springen, sonst überschreiben sich die 128 Byte immer
selbst.....

Vor der Procedur sollte auch noch der Event abgefragt werden,
ob überhaupt Netzwerksdaten anliegen....

Generell sollte man Dateien mit SendNetworkData - ReceiveNetworkData
nicht ohne ein Handshaking übermitteln, d.h. vor dem Senden
die Dateilänge und den Dateinamen (ist ja ev. auch interessant)
übertragen, dann die Datei zu senden und danach den Empfang zu
bestätigen (der Client sollte ja auch wissen daß die Übertragung fertig ist..)

Das Thema Network ist beliebig kompliziert ..... :wink:

Cu von Team100
Kompliziert kann es jeder lösen, aber das wirklich Geniale ist einfach.....
Benutzeravatar
DataMiner
Beiträge: 220
Registriert: 10.10.2004 18:56

Beitrag von DataMiner »

(ich hänge mich mal ganz dreist an dieses Thema dran)
Nehmt Rücksicht auf einen Anfänger und zerreisst mich nicht gleich in der Luft ;)
Gibt es eigentlich irgendwo einen (brauchbaren) Codeschnipsel zum Thema "Senden und Empfangen von Dateien im Netzwerk". Alles was ich bis jetzt in die Finger bekommen habe, hat mich nicht so ganz befriedigt.
Vor allem, wie handelt man das, wenn sich mehr als 10 Clients (mehr oder weniger gleichzeitig) mit Dateien melden? - Da macht mein Proggi immer die Tür zu.

@Team100
Du scheinst ja voll die Kenne von der Materie zu haben. Hast du auch so ganz zufällig nen Codeschnipsel zur Hand??
:mrgreen: :mrgreen: :mrgreen: :mrgreen:
Team100
Beiträge: 104
Registriert: 13.09.2004 22:59

Beitrag von Team100 »

@DataMiner

.... gerne würde ich Codes für Mehrfach-Clients posten, aber da muß
ich wohl auch noch viel lernen ...... auch wird man um einen entsprechenden
Versuchsaufbau mit einer entsprechenden Anzahl
PCs in einem lokalen Netzwerk nicht herumkommen. Wenn das dann
läuft, kann man es in der weiten Welt versuchen..... alles andere
ist zu viel Abenteuer.

Was ich realisiert habe ist die Übertragung großer Datenmengen
innerhalb von Firmennetzwerken, allerdings ist hier immer nur
1 Client aktiv. Die anderen Clients melden zwar, daß sie was senden wollen,
müssen aber die paar Sekunden warten bis sie dran sind.......
das stört im Backoffice nicht (läuft im Hintergrund), für Spiele
ist Zuwarten unbrauchbar.

Ein ausgezeichneter Ansatz für eine API Lösung ist
http://jconserv.net/purebasic/viewtopic ... 4fe7e0c525

Im Besonderen könnte der Beitrag von tranquil interessant
sein, wo die Errorcodes abgefragt werden.
Wenn es gelingen würde, diese Errorcodes auch bei
Anwendung der PB-Network-Befehle auszulesen
(eventuell mit GetLastError_), dann müßte man nicht
die dort verwendeten API-Network-Befehle verwenden.

Leider hat bisher die Zeit gefehlt das Thema Errorcodes
zu erforschen..... Ich glaube aber, daß man bei der Verwendung
von 10 Clients auf einmal um dieses Thema nicht herumkommen wird.

Bei meiner jetztigen Applikation (mit 1 aktiven Client) wird
die Prüfsumme des Datenblockes (= Teilmenge der zu übertragenen
Datei mitgegeben) mitgegeben. Paßt was nicht, wird der Block
erneut gesendet.... Kein Problem wenn genug Zeit da ist,
für einen Multiplayer-Shooter ist die Methode aber unbrauchbar.

Wie gesagt, das Thema Network ist beliebig kompliziert :wink:

Cu von Team100
Kompliziert kann es jeder lösen, aber das wirklich Geniale ist einfach.....
Benutzeravatar
DataMiner
Beiträge: 220
Registriert: 10.10.2004 18:56

Beitrag von DataMiner »

DANKE!

Ist zwar nicht so das ich ein grosser Kenner der Win-Api wäre...

... Aber der Chat-Server sieht interessant aus, vor allem wegen dem Error-handling.

Wie heisst es so schön - schaun wa ma.

Danke nochmal :allright:
Benutzeravatar
DataMiner
Beiträge: 220
Registriert: 10.10.2004 18:56

Beitrag von DataMiner »

http://jconserv.net/purebasic/viewtopic ... 4fe7e0c525
Tja, hat sich was mit "Error-Handling"...
Zum einen ist nicht abgefangen ob ein User schon angemeldet ist, sprich connect-Button festhalten (bzw. 100x klicken) und Server macht Bumm, zum anderen funktioniert genau die Funktion nicht, die ich brauche: send
Irgendwie / irgendwo läuft sich die Prozedur mysend tot. Ich habe nur keinen Schimmer wo. Es kommt einfach nix an, oder ich bin zu blöd die gesendete Datei zu finden.

HILFE!!!

:cry:
netfreak
Beiträge: 91
Registriert: 23.10.2004 18:30
Kontaktdaten:

Beitrag von netfreak »

Noch eine kurte Frage! Um eine Datei Stück für Stück zusenden muss ich sie doch ganz normal mit readfile auslesen oder?

mfg
netfreak

Und danke für eure Hilfe!
mfg
netfreak
Team100
Beiträge: 104
Registriert: 13.09.2004 22:59

Beitrag von Team100 »

@DataMiner

...der erwähnte Code von Tranquil ist als Rohgerüst anzusehen,
soll auch nicht mehr sein. Das mehrmalige Anmelden kann man
z.B. durch Speichern und Vergleichen des nicknames vom Client
verhindern. Es ist ja ohnedies interessant, Nutzungzeiten und
Anmeldungen der Nicks auszuwerten.

Leider habe ich im Moment keine Testmöglichkeit, aber ich erinnere
mich im Vorjahr den Code schon (mit kleinen Veränderungen?)
zum Laufen gebracht zu haben...... das war jedoch mit PB 3.91
Suchen, Testen und Geduld führt zum Ziel.... Eventuell ist es
günstig sich im englischen Forum anzumelden und Tranquil
in einer PM zu fragen, ob es ein Update gibt.

@netfreak

Die Datei mit ReadFile öffnen und mit ReadData in den Speicher
lesen, mit SendNetworkData senden, dabei den Rückgabewert
kontrollieren, ob auch die gesamte Bytezahl gesendet wurde, sonst
Rest nachsenden. Danach nicht vergessen den Speicher freizugeben.

Es gibt eine Fülle von einfachen Beispielen im Codearchiv,
auch die Suchfunktion im Forum mit den entspechenden
Befehlen gibt Ergebnisse.

Die zuverlässigen Beispiele erkennt man daran, daß die
Rückgabewerte von SendNetworkData und ReceiveNetworkData
ausgewertet werden ..... <)

Zum Testen von Dateiübertragungen empfiehlt sich die
Erstellung einer Testdatei mit eindeutig identifizierbaren
Inhalt, z.B. bestehend aus Zeilen mit einer fortlaufenden
5-stelligen Zeilennummerierung am Anfang, dann dem Alphabet.
(Hier leistet ein kleines PB-Programm Hilfe beim Erstellen....)

Die empfangene Testdatei kann man mit einem Editor bequem
ansehen und sieht auf den ersten Blick ob was fehlt oder falsch
zusammengesetzt ist ......

Viel Erfolg ...

Cu von Team100
Kompliziert kann es jeder lösen, aber das wirklich Geniale ist einfach.....
Benutzeravatar
stbi
Beiträge: 685
Registriert: 31.08.2004 15:39
Wohnort: Cleverly Hills

Beitrag von stbi »

Sorry, aber ich kann die Probleme mit SendNetworkFile/ReceiveNetworkFile nicht nachvollziehen, bei mir funktioniert das. Ich habe das gerade nochmal auf Basis der Beispiel-Programme ausprobiert - null problemo.

Meine Testdatei war 21 MB groß. Mir ist dabei aufgefallen, dass der Clientprozess bei SendNetworkFile erstmal 21 MB Speicher allokiert hat ... anscheinend lutscht er sich die Datei erstmal in den Speicher bevor er sendet. Das ist eigentlich mehr als überflüssig, und ich würde vermuten, dass es beim Senden größerer Dateien unweigerlich knallt. Wobei der Leidtragende durchaus der Serverprozess sein kann, der plötzlich keine Daten mehr bekommt und mit 100% CPU-Last ganz schnell wartet :mrgreen:
PB 4.02 XP Pro SP2 "Der Code ist willig, aber der Prozessor ist schwach."

Es gibt keine Vista-Witze. Es ist alles wahr!
netfreak
Beiträge: 91
Registriert: 23.10.2004 18:30
Kontaktdaten:

Beitrag von netfreak »

@stbi: Allein das er doch diese 100% verbraucht! und das er es ganz in die Ram ladet ist doch schon sch**ße!
mfg
netfreak
Antworten