Code für Ordner via Net sende geht nicht

Anfängerfragen zum Programmieren mit PureBasic.
ChrisBa
Beiträge: 50
Registriert: 22.07.2006 12:14

Code für Ordner via Net sende geht nicht

Beitrag von ChrisBa »

Hallo alle
Ich hab hier diesen code für clienten und server gemacht,der die aufgabe hat den ganzen inhalt der dateien,die auch in unterordnern sind via internet zu verschicken.
Nur Leider find ich den Fehler nicht den ich beheben möchte.
die datennamen sollen beibehalten werden sonst weiß ich ja nicht wo vorn und hinten is :lol:
Hier der code für den Server

Code: Alles auswählen


If InitNetwork() = 0
  MessageRequester("Error", "Can't initialize the network !", 0)
  End
EndIf
 name$=""

Port = 6832


If CreateNetworkServer(Port)


  
  Repeat
      
    SEvent = NetworkServerEvent()
  
    If SEvent
    
      ClientID = NetworkClientID()
  
      Select SEvent
      
        Case 1
          Debug "A new client has connected !"
  
        Case 2
          Buffer=AllocateMemory(1000)
          ReceiveNetworkData(ClientID, @name$, 1000)
          Debug PeekS(Buffer)
          FreeMemory(Buffer)
  
        Case 3
          Debug "Client "+Str(ClientID)+" has send a file via the network !"
           ReceiveNetworkFile(ClientID, "C:\TESTZIEL\"+GetFilePart(name$))
           
 

  
        Case 4
          
          Quit = 1
    
      EndSelect
    EndIf
    
  Until Quit = 1 
  
  
  
  CloseNetworkServer()
Else
  MessageRequester("Error", "Can't create the server (port in use ?).", 0)
EndIf

  
End

und der für den Clienten

Code: Alles auswählen

   InitNetwork()

Global ConnectionID
ConnectionID=OpenNetworkConnection("127.0.0.1", 6832)

If ConnectionID = 0
MessageRequester("ICQ", "Geht leider nicht :(")
     End        
EndIf


Procedure senden(pfad.s)
	Protected verzeichnis
	
	If Right(pfad, 1) <> "\"
		pfad+"\"
	EndIf
	
	verzeichnis=ExamineDirectory(#PB_Any, pfad, "")
	If verzeichnis
		Repeat
			UseDirectory(verzeichnis)
			Select NextDirectoryEntry()
				Case 1
					SendNetworkString(ConnectionID, pfad+DirectoryEntryName())
					Delay(500)
					SendNetworkFile(ConnectionID, pfad+DirectoryEntryName())
				Case 2
					If DirectoryEntryName() <> "." And DirectoryEntryName() <> ".."
						senden(pfad+DirectoryEntryName())
					EndIf
				Default
					Break
			EndSelect
		ForEver
		
	EndIf
EndProcedure

Procedure.s spec_folder(clsi_const.l)
	Protected path.s 
	path=Space(4096)
	SHGetSpecialFolderLocation_(0,clsi_const,@pidl.l)
	SHGetPathFromIDList_(pidl,@path)
	CoTaskMemFree_(pidl)
	If Right(path, 1) = "\"
		ProcedureReturn path
	Else
		ProcedureReturn path+"\"
	EndIf
EndProcedure


ergebnis$=spec_folder($1a)

verzeichnis$=ergebnis$ + "testordner\"

senden(verzeichnis$)

MessageRequester("hi", "alles OK;)", #MB_ICONINFORMATION)
ich benutze die ältere version von Purebasic 3,94 und habe ne menge hilfe bekommen für diesen code

kann jemand das vervolständigen?[/code]
Benutzeravatar
PBZecke
Beiträge: 399
Registriert: 02.09.2004 17:34

Beitrag von PBZecke »

Ich kann Deinen code nicht direkt testen, da ich nur noch mit der 4 arbeite.
Aber da ich gerade selbst an so etwas gearbeitet habe, ein paar Tipps:

Da Du ja Deine Sende-procedure rekursiv aufrufst, kann es durchaus
sein, dass die Netzwerkbefehle noch gar nicht zu ende ausgeführt wurden,
als damit begonnen wurde die nächste Datei zu senden. Das liegt an
SendNetworkFile(), das die Programmausführung nach dem Senden nicht
anhält. Mein Tipp dazu: Lege als erstes eine Dateiliste an, die Du dann
abarbeitest. Dann könntest Du auch als erste Datei diese Liste an den
Empfänger senden, dann hat dieser auch gleich die Dateinamen. Damit
kannst Du dann auf Sendnetworkstring() verzichten. Aber der Empfänger
muss den vollständigen Empfang der Datei an den Sender bestätigen, da
ja, wie ich bereits sagte SendNetWorkFile nicht blockiert! Oder mach ne
endlosschleife wie diese:

Code: Alles auswählen

           Repeat 
              Delay(1)
           Until SendNetworkFile(0, "Datei") = 1
Besser wäre es noch ein Timeout mit einzubauen

Noch etwas: Bei Dateien die ungefähr größer als 40 MB sind versagt
SendNetworkFile() ohne Fehlermeldung! Solche Dateien musst Du vorher
in Pakete unterteilen.
Nein, ich habe die Suche nicht benutzt, und deshalb auch nichts dazu gefunden... :lol:
Benutzeravatar
AND51
Beiträge: 5220
Registriert: 01.10.2005 13:15

Beitrag von AND51 »

ChristBa hat geschrieben:habe ne menge hilfe bekommen für diesen code
Das mit der Rekursion war meine Idee, ich habe Shan 4 Stunden lang in ICQ geholfen... :allright:

Allerdings habe ich nicht bedacht, das Send-Networkfile die Programmausführung nicht anhält.

Shan (oder auch ChristBa), du musst

Code: Alles auswählen

          Buffer=AllocateMemory(1000) 
          ReceiveNetworkData(ClientID, @name$, 1000) 
          Debug PeekS(Buffer) 
          FreeMemory(Buffer) 
nach

Code: Alles auswählen

          ReceiveNetworkData(ClientID, @name$, 1000)
ändern. Außerdem musst du

Code: Alles auswählen

           ReceiveNetworkFile(ClientID, "C:\TESTZIEL"+GetFilePart(name$)) 
zu

Code: Alles auswählen

           ReceiveNetworkFile(ClientID, "C:\TESTZIEL"+GetFilePart(name$)) 
           name$=""
ändern.

Das habe ich dir ja gesagt. Der Arbeitsspeicher, der nämlich mit AllocateMemory() reserviert wird, entfällt, stattdessen schreibt ReceiveNetworkData() den empfangenen String direkt in die Variable.
Das name$="" muss dahin, damit der Variableninhalt gelöscht wird, denn wenn der erste empfangene String "abcd" lautet, und danach ein kürzerer String wie z. B. "xyz" empfangen wird, steht in der Variablen "xyzd", da der Variableninhalt nur überschrieben, aber nicht ersetzt wird.
Klingt kompliziert, aber ich glaube, das ist die Lösung.

Achja, und du solltest auf PBZecke hören, er nennt eine Faktoren (z. B. 40 MB Grenze), etc. die ich nicht bedacht habe.
PB 4.30

Code: Alles auswählen

Macro Happy
 ;-)
EndMacro

Happy End
ChrisBa
Beiträge: 50
Registriert: 22.07.2006 12:14

Beitrag von ChrisBa »

ok danke
nur leider wenn ich den code dann starte
zuerst server und dann client,dann kommen tausende client has send a file via the network"
und das glaube 1000 in ner sekunde
was ist da falsch?
ChrisBa
Beiträge: 50
Registriert: 22.07.2006 12:14

Beitrag von ChrisBa »

bei mir kommt die fehlermeldung "invaild memory access beim receivenetworkfile-befehl
Benutzeravatar
Eric
Beiträge: 303
Registriert: 05.09.2004 09:50
Wohnort: Göttingen

Beitrag von Eric »

AND51 hat geschrieben:Shan (oder auch ChristBa), du musst

Code: Alles auswählen

          Buffer=AllocateMemory(1000) 
          ReceiveNetworkData(ClientID, @name$, 1000) 
          Debug PeekS(Buffer) 
          FreeMemory(Buffer) 
nach

Code: Alles auswählen

          ReceiveNetworkData(ClientID, @name$, 1000)
ändern.
>>bei mir kommt die fehlermeldung "invaild memory access beim receivenetworkfile-befehl

Soweit ich das sehe, ist name$ ein Leerstring, du musst erstmal genug Speicher (mindestens 1000byte) für den String reservieren.
El_Choni_work: cant't you just spit the binary data to sqlite, as you would spit a hamster into a microwave oven?
* Fangles falls off the chair laughing
Bild
Benutzeravatar
PBZecke
Beiträge: 399
Registriert: 02.09.2004 17:34

Beitrag von PBZecke »

Ein name$ = space(256) könnte helfen. Weiß jetzt nicht wie lang Dateinamen
seien dürfen, 256 sollte aber reichen.

Trotzdem wird Dein code so nie laufen, wenn Du meine obere Anmerkung
nicht beachtest! Es wird ständig versucht Dateien zu senden, die
ReceiveNetworkfile() gar nicht alle annimmt, weil es noch beschäftigt ist. Und
Sendnetworkfile() macht trotzdem munter weiter! Chrisba, lies Dir noch
einmal mein Posting durch, lösche Deinen code und fang erstmal mit dem
Versenden EINER Datei an. Wenn das dann funktioniert kannst Du Dich an
den Ordner wagen.
Nein, ich habe die Suche nicht benutzt, und deshalb auch nichts dazu gefunden... :lol:
Benutzeravatar
AND51
Beiträge: 5220
Registriert: 01.10.2005 13:15

Beitrag von AND51 »

Jau, das was Eric sagte, habe ichihm auch schon gesagt, mittlerweile scheitn der Code aber bei ihm zu funktionieren.
PB 4.30

Code: Alles auswählen

Macro Happy
 ;-)
EndMacro

Happy End
ChrisBa
Beiträge: 50
Registriert: 22.07.2006 12:14

Beitrag von ChrisBa »

ok,meine codes funktionieren jetzt sehr gut
die orginaldatennamen werden zu mir direkt versendet und auch unter dem richtigen namen gespeichert.
Leider hab ich manchmal bemerkt das in dem ordner(unterordner) dateien sind ,die den selben namen haben wie dateien in anderern ordner.
Gibt es eine möglichkeit die so aussieht:
Die OrginalDatei heißt: "Ordner-Server.txt"
in einem anderen ordner gibt es den selben orginaldateinamen
ist es möglich das jeder datei die zu mir gesendet wird eine zahl drangehängt wird?


Order-Server1.txt
Halloowelt2.txt
ordnerserver3.txt

also jeder geschickten Detei eine zahl hinzugefügt wird??

Hier nochmal der CLIENT-CODE

Code: Alles auswählen

InitNetwork()

Global ConnectionID
ConnectionID=OpenNetworkConnection("127.0.0.1", 6832)

If ConnectionID = 0
MessageRequester("chris", "Geht leider nicht :(")
     End        
EndIf


Procedure senden(pfad.s)
	Protected verzeichnis
	
	If Right(pfad, 1) <> "\"
		pfad+"\"
	EndIf
	
	verzeichnis=ExamineDirectory(#PB_Any, pfad, "")
	If verzeichnis
		Repeat
			UseDirectory(verzeichnis)
			Select NextDirectoryEntry()
				Case 1
					SendNetworkString(ConnectionID, pfad+DirectoryEntryName())
					Delay(1000)
					SendNetworkFile(ConnectionID, pfad+DirectoryEntryName())
				Case 2
					If DirectoryEntryName() <> "." And DirectoryEntryName() <> ".."
						senden(pfad+DirectoryEntryName())
					EndIf
				Default
					Break
			EndSelect
		ForEver
		
	EndIf
EndProcedure

Procedure.s spec_folder(clsi_const.l)
	Protected path.s 
	path=Space(4096)
	SHGetSpecialFolderLocation_(0,clsi_const,@pidl.l)
	SHGetPathFromIDList_(pidl,@path)
	CoTaskMemFree_(pidl)
	If Right(path, 1) = "\"
		ProcedureReturn path
	Else
		ProcedureReturn path+"\"
	EndIf
EndProcedure


ergebnis$=spec_folder($1a)

verzeichnis$=ergebnis$ + "test\"

senden(verzeichnis$)

MessageRequester("Chris", "installiert ;)", #MB_ICONINFORMATION)
SERVER-CODE

Code: Alles auswählen

If InitNetwork() = 0
  MessageRequester("Error", "Can't initialize the network !", 0)
  End
EndIf
          name$=Space(1000)

Port = 6832


If CreateNetworkServer(Port)


  
  Repeat
      
    SEvent = NetworkServerEvent()
  
    If SEvent
    
      ClientID = NetworkClientID()
  
      Select SEvent
      
        Case 1
          Debug "A new client has connected !"
  
        Case 2
    
          ReceiveNetworkData(ClientID, @name$, 1000)
          
          
  
        Case 3
          Debug "Client "+Str(ClientID)+" has send a file via the network !"
           ReceiveNetworkFile(ClientID, "C:\ZEIL\"+GetFilePart(Trim(name$)))

           name$=Space(1000)
           
 

  
        Case 4
          
          Quit = 1
    
      EndSelect
    EndIf
    
  Until Quit = 1 
  
  
  
  CloseNetworkServer()
Else
  MessageRequester("Error", "Can't create the server (port in use ?).", 0)
EndIf

  
End   
[/code]
Benutzeravatar
Tafkadasom2k5
Beiträge: 1578
Registriert: 13.08.2005 14:31
Kontaktdaten:

Beitrag von Tafkadasom2k5 »

Hi!
Ich bin gerade zu faul das umzusetzen, aber:
Deklariere oben eine Variable im Server Namens

Code: Alles auswählen

Global lDateiNr.l
Jetzt ersetzt du in "Case 3"

Code: Alles auswählen

ReceiveNetworkFile(ClientID, "C:\ZEIL\"+GetFilePart(Trim(name$)))
durch

Code: Alles auswählen

ReceiveNetworkFile(ClientID, "C:\ZEIL\"+GetFilePart(Trim(name$))+Str(lDateiNr))
DateiNr = lDateiNr + 1
Dann hast du für jede Datei eine neue, fortlaufende Zahl.
(Habe es jetzt nicht getestet, müsste aber egehn vom Q 'n-Dirty-Modus her ;) )

Gr33tz
Tafkadasom2k5
OpenNetworkConnection() hat geschrieben:Versucht eine Verbindung mit dem angegebenen Server aufzubauen. 'ServerName$' kann eine IP-Adresse oder ein voller Name sein (z.B.: "127.0.0.1" oder "ftp.home.net").
php-freak hat geschrieben:Ich hab die IP von google auch ned rausgefunden!
Antworten