dateien übers netzwerk via sendnetworkdata senden

Für allgemeine Fragen zur Programmierung mit PureBasic.
Kevin
Beiträge: 236
Registriert: 11.06.2007 12:55

Re: dateien übers netzwerk via sendnetworkdata senden

Beitrag von Kevin »

Moxl hat geschrieben:wie schreibt ihr das denn immer wenn ihr große dateien verschicken wollt? :praise:
Ich würde dass so machen:

Server:

Code: Alles auswählen

XIncludeFile "NET.pbi"
InitNET()

InitNetwork()
OpenConsole()

host$="localhost"
port=1337

If Not CreateNetworkServer(0,port)
  End
EndIf

#packet_NewFile = $01; client -> server: neue datei
#packet_FileData = $02; client -> server: datei daten
#packet_NextData = $03; server -> client: frägt nach weitren daten

Repeat
  
  serverevent=NetworkServerEvent()
  If  serverevent=#PB_NetworkEvent_Data
    clientid=EventClient() : clientid$=Str(clientid) : clientip$=IPString(GetClientIP(clientid))
    
    If ReceivePacket(clientid)=1
      pos=PacketBuffer();pointer zu den daten die geladen wurden
      
      Select GetPacketID()
        Case #packet_NewFile;{ 
          state=PeekA(pos):pos+1; status 1=komplett gesended 2=es folgen noch daten
          myPeekS(pos,CurrentFile$); dateiname
          CurrentFileLen=PeekL(pos):pos+4; datei größe
          
          CurrentFile=CreateFile(#PB_Any,"receive_"+CurrentFile$)
          
          If CurrentFile
            PrintN("create new file! received: 0 / "+Str(CurrentFileLen)+" bytes")
          Else
            PrintN("error: cant create file")
          EndIf
          
          If state=1;wenn es alle daten waren
            CloseFile(CurrentFile):CurrentFile=0
            PrintN("datei '"+CurrentFile$+"' wurde geladen!")
          Else
            SendPacket(clientid,#packet_NextData,0); weitere daten anfordern
          EndIf
          ;}
        Case #packet_FileData;{
          state=PeekA(pos):pos+1; status 1=komplett gesended 2=es folgen noch daten
          datalen=PeekL(pos):pos+4; größe der gesendeten daten
          
          If datalen; wenn daten geschickt wurden...
            WriteData(CurrentFile,pos,datalen); ...werden sie eingelesen
          EndIf
          PrintN("receive data "+Str(Lof(CurrentFile))+" / "+Str(CurrentFileLen)+" bytes")
          
          If state=1;wenn es alle daten waren
            CloseFile(CurrentFile):CurrentFile=0
            PrintN("datei '"+CurrentFile$+"' wurde geladen!")
          Else
            SendPacket(clientid,#packet_NextData,0); weitere daten anfordern 
          EndIf
          ;}
      EndSelect

    Else
      PrintN("receive data error!")
    EndIf
    
  Else
    Delay(1)
  EndIf
  
ForEver
Client:

Code: Alles auswählen

XIncludeFile "NET.pbi"
InitNET()

InitNetwork()
OpenConsole()
host$="localhost"
port=1337

verbindung=OpenNetworkConnection(host$, port)

#packet_NewFile = $01; client -> server: neue datei
#packet_FileData = $02; client -> server: datei daten
#packet_NextData = $03; server -> client: frägt nach weitren daten

; ##### ##### ##### #####

If  verbindung=0
  ConsoleColor(12, 0)
  PrintN("nicht hergestellt!")
  ConsoleColor(7, 0)
  Input()
  End
Else
  ConsoleTitle("Verbindung mit <"+host$+"> Port: <"+Str(port)+">")
  ConsoleColor(14, 0)
  PrintN("hergestellt! Port "+Str(port)+"")
  PrintN("")
  ConsoleColor(7, 0)
  Print(">")
  
  Repeat
    
    If  Inkey()<>"";wenn eine taste gedrückt wird...
      If CurrentFile
        PrintN("error "+CurrentFile$+" muss erst gesendet werden...")
      Else
        datei$=OpenFileRequester("", "", "Alle Dateien | *.*", 0)
        
        CurrentFile=ReadFile(#PB_Any,datei$)
        If CurrentFile
          CurrentFileLen=Lof(CurrentFile) : CurrentFileSended=0
          
          ;{ #packet_NewFile : packet das dem server die größe und den namen der datei sendet
          pos=PacketBuffer()
          
          If CurrentFileLen=0
            state=1; datei fertig gesendet da 0 bytes groß
          Else
            state=2; sagen dass nach diesen daten noch weitere kommen
          EndIf
          PokeA(pos,state):pos+1
          
          myPokeS(pos,GetFilePart(datei$)); datei name
          
          PokeL(pos,CurrentFileLen):pos+4; datei größe
          
          If state=1; datei schließen wenn alles gesendet wurde
            CloseFile(CurrentFile):CurrentFile=0
          EndIf
          
          If SendPacket(verbindung, #packet_NewFile, pos-PacketBuffer()) = -1
            PrintN("Error: cant send data!")
          Else
            PrintN("sended "+Str(CurrentFileSended)+" / "+Str(CurrentFileLen)+" bytes")
          EndIf
          ;}          
          
        Else
          PrintN("error cant open file!")
        EndIf
        
      EndIf
    EndIf
    
    clientevent=NetworkClientEvent(verbindung)
    If clientevent=#PB_NetworkEvent_Data
      
      If ReceivePacket(verbindung)=1
        pos=PacketBuffer()
        
        Select GetPacketID()
          Case #packet_NextData;{ client fordert weitere daten
            If CurrentFile
              pos=PacketBuffer()
              
              rest=CurrentFileLen-CurrentFileSended;ermitteln wie viel noch gesendet werden muss
              
              If rest>1024
                rest=1024; soll maximal 1024byte der datei senden
                state=2; sagen dass nach diesen daten noch weitere kommen
              Else
                state=1; sagen dass alle daten gesendet wurden
              EndIf
              PokeA(pos,state):pos+1
              
              PokeL(pos,rest):pos+4; wie viele daten folgen
              
              ReadData(CurrentFile, pos, rest):pos+rest; daten einlesen
              
              If state=1; datei schließen wenn alles gesendet wurde
                CloseFile(CurrentFile):CurrentFile=0
              EndIf
              
              If SendPacket(verbindung, #packet_FileData, pos-PacketBuffer()) = -1
                PrintN("Error: cant send data!")
              Else
                CurrentFileSended+rest
                PrintN("sended "+Str(CurrentFileSended)+" / "+Str(CurrentFileLen)+" bytes")
              EndIf
              
            Else
              PrintN("error! l:"+Str(#PB_Compiler_Line))
            EndIf
            ;}
        EndSelect
      EndIf
      
    Else
      Delay(1)
    EndIf
    
  ForEver
EndIf
Include:

Code: Alles auswählen

Procedure NET_SendData(NetID, *buffer, size, TimeOut=2000)
  Protected time,buf,error
  time=ElapsedMilliseconds()
  Repeat
    buf=SendNetworkData(NetID,*buffer,size)
    If buf>0
      size-buf
      If size=0
        ProcedureReturn 1
      EndIf
      *buffer+buf
      time=ElapsedMilliseconds()
    ElseIf buf=-1
      If error=10
        Break
      Else
        error+1
      EndIf
      Delay(30)
    EndIf
    Delay(1)
  Until ElapsedMilliseconds()-time=>TimeOut
  ProcedureReturn -1
EndProcedure
Procedure NET_ReceiveData(NetID, *buffer, size, TimeOut=2000)
  Protected time,buf,error
  time=ElapsedMilliseconds()
  Repeat
    buf=ReceiveNetworkData(NetID,*buffer,size)
    If buf>0
      size-buf
      If size=0
        ProcedureReturn 1
      EndIf
      *buffer+buf
      time=ElapsedMilliseconds()
    ElseIf buf=-1
      If error=10
        Break
      Else
        error+1
      EndIf
      Delay(10)
    EndIf
    Delay(1)
  Until ElapsedMilliseconds()-time=>TimeOut
  ProcedureReturn -1
EndProcedure

#NET_HeaderLength=5
Global NET_BufferLength, *NET_BufferH, *NET_Buffer

Macro PacketBuffer()
  *NET_Buffer
EndMacro
Macro SetPacket(ID,length)
  PokeA(*NET_BufferH, ID)
  PokeL(*NET_BufferH+1, length)
EndMacro
Macro GetPacketID()
  PeekA(*NET_BufferH)
EndMacro
Macro GetPacketLength()
  PeekL(*NET_BufferH+1)
EndMacro

Procedure SendPacket(NetID, ID, length)
  SetPacket(ID, length)
  ProcedureReturn NET_SendData(NetID, *NET_BufferH, length+#NET_HeaderLength)
EndProcedure
Procedure ReceivePacket(NetID)
  Protected len
  If NET_ReceiveData(NetID, *NET_BufferH, #NET_HeaderLength)<>-1
    len=GetPacketLength()
    If len=>0 And len=<NET_BufferLength
      If len=0 Or NET_ReceiveData(NetID, *NET_Buffer, len)=1
        ProcedureReturn #True
      EndIf
    EndIf
  EndIf
  ProcedureReturn -1
EndProcedure

Macro myPokeS(mempos,string); schreib string und addiert anschließend mempos mit dem benötigte speicherplatz
  PokeS(mempos,string,-1,#PB_Unicode):mempos+(Len(string)+1)*2
EndMacro
Macro myPeekS(mempos,out_string); **
  out_string=PeekS(mempos,-1,#PB_Unicode):mempos+(Len(out_string)+1)*2
EndMacro

Procedure InitNET(BufferLength=8192); erstellt buffer
  NET_BufferLength=BufferLength
  *NET_BufferH=AllocateMemory(#NET_HeaderLength+BufferLength)
  *NET_Buffer=*NET_BufferH+#NET_HeaderLength
EndProcedure

;EOF
gibt bestimmt einfachere Lösungen aber so funktioniert es...

mfg kevin

[edit 06.08.2013] bug behoben
Zuletzt geändert von Kevin am 06.08.2013 19:27, insgesamt 1-mal geändert.
Moxl
Beiträge: 150
Registriert: 26.10.2012 13:19

Re: dateien übers netzwerk via sendnetworkdata senden

Beitrag von Moxl »

ach du scheiße :bounce:
Moxl
Beiträge: 150
Registriert: 26.10.2012 13:19

Re: dateien übers netzwerk via sendnetworkdata senden

Beitrag von Moxl »

also aus dem code wirrwarr erkenn ich leider gar nix :cry:

ich bräucht nur ma ne gescheite lösung wie man ne datei in pakete zerlegt, diese verschickt und aufm server die einzelnen pakete empfängt und wieder gescheit zusammenfügt :praise:
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7039
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: dateien übers netzwerk via sendnetworkdata senden

Beitrag von STARGÅTE »

Aber genau das macht doch der Code von Kevin.

"nur mal eben" ist sowas einfach nicht möglich.

Kevins Code kommt dir vielleicht viel vor, weil er (richtigerweise) ein Paketsystem erstellt hat, sodass immer genau erkennbar ist, was da über das Netzwerk gesendet wird.

Du kannst nicht einfach eine Datei in 4 Blöcke zerlegen und dann die 4 Blöcke rüber schicken.
Der Partner weiß nun mal nicht auf wie viel Blöcke er warten soll und wenn mehr kommen, welche Blöcke zu welcher Datei gehören.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Antworten