dateien übers netzwerk via sendnetworkdata senden

Für allgemeine Fragen zur Programmierung mit PureBasic.
Moxl
Beiträge: 150
Registriert: 26.10.2012 13:19

dateien übers netzwerk via sendnetworkdata senden

Beitrag von Moxl »

hallo an alle,

also ich hab mehrmals die sufu benutzt aber leider nichts brauchbares gefunden.
Also ich habe gehört das Sendnetworkdata() besser sei als SendnetworkFile(), warum genau wäre meine erste frage? :D

und nun, wie mache ich das genau mit sendnetworkdata()?
ich lese eine datei aus,
reserviere speicher in der größe der datei,
schicke den speicherbereich via sendnetworkdata(),

so wie genau empfange ich das jetzt?
der client/server der die datei empfangen soll weiß ja nicht wie groß die datei bzw. die daten sind die empfangen werden sollen... also woher weiß ich wie viel speicher ich reservieren muss um die daten wiederrum in eine datei zu schreiben?

vielen dank schonmal im vorraus :)
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 »

Moxl hat geschrieben:Also ich habe gehört das Sendnetworkdata() besser sei als SendnetworkFile(), warum genau wäre meine erste frage?
Weil der Code dieser Funktion veraltet ist, und hier und da Fehler machen könnte.
Moxl hat geschrieben:und nun, wie mache ich das genau mit sendnetworkdata()?ich lese eine datei aus,reserviere speicher in der größe der datei,schicke den speicherbereich via sendnetworkdata(),
Ist die Datei "klein", kannst du den Speicher mit AllocateMemory() komplett reservieren, die Datei mit ReadData() drot hinein lesen und dann den Speicher mit SendNetworkData() verschicken.
so wie genau empfange ich das jetzt?
der client/server der die datei empfangen soll weiß ja nicht wie groß die datei bzw. die daten sind die empfangen werden sollen... also woher weiß ich wie viel speicher ich reservieren muss um die daten wiederrum in eine datei zu schreiben?
Du kannst dir ein eigenes kleines Protokoll schreiben, in dem du zB. erst Dateigröße (und Name+Nameslänge) schickst und danach erst den Dateiinhalt.
Als Empfänger list du dann erst die Dateigröße in einen kleinen Speicher (zB Long oder Quad) und weiß dann, wie viel du als nächstes reservieren musst für den Inhalt und ggf. den Namen.

Willst du mehr als nur Dateien verschicken, empfiehlt es sich sowieso dir ein eigenes Protokoll anzulegen, sodass du immer eine "Identifikations" vorweg schickst, damit der andere weiß, was nun kommt.
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
Moxl
Beiträge: 150
Registriert: 26.10.2012 13:19

Re: dateien übers netzwerk via sendnetworkdata senden

Beitrag von Moxl »

ok und wie genau sende ich informationen vorweg?

also sonst mache ich das immer so ich schicke mit sendnetworkstring() immer strings hin und her und zwar so: sendnetworkstring(verbindung, "dateisenden"+chr(28)+"name"+Chr(28)+"größe usw....)
der client bzw server liest dann den empfangenen string mittels stringfield() aus also wenn der erste index "dateisenden" ist dann weiß der client/server bescheid was für infos jetzt kommen...

macht man das so? und sollte ich das dann genauso weiter machen?


und ich sehe grade das ich nur höchstens 64kb mit einem sendnetworkdata() senden kann (wenn ich mich nich verguckt habe) ... was wenn meine datei größer ist? zB ein bild mit ca 1MB?
Benutzeravatar
RSBasic
Admin
Beiträge: 8047
Registriert: 05.10.2006 18:55
Wohnort: Gernsbach
Kontaktdaten:

Re: dateien übers netzwerk via sendnetworkdata senden

Beitrag von RSBasic »

STARGÅTE hat geschrieben:
Moxl hat geschrieben:Also ich habe gehört das Sendnetworkdata() besser sei als SendnetworkFile(), warum genau wäre meine erste frage?
Weil der Code dieser Funktion veraltet ist, und hier und da Fehler machen könnte.
Außerdem, wenn man SendnetworkFile() fürs Senden einer Datei nutzt, weiß man nie, wie viel Bytes bereits gesendet wurden. Daher kannst du auch nicht ermitteln, wie lange dieser Sende-Vorgang dauern wird.
Wenn du das mit dem Senden mit Sendnetworkdata() machst, dann schickst du die Datei in mehreren kleinen Paketen und kannst mit Hilfe dieser Information (Anzahl der bereits empfangenen Daten) einen ProgressBarGadget erstellen und den Statuswert in Echtzeit ändern, damit der Benutzer sieht, wie weit der Vorgang ist.
Aus privaten Gründen habe ich leider nicht mehr so viel Zeit wie früher. Bitte habt Verständnis dafür.
Bild
Bild
Benutzeravatar
RSBasic
Admin
Beiträge: 8047
Registriert: 05.10.2006 18:55
Wohnort: Gernsbach
Kontaktdaten:

Re: dateien übers netzwerk via sendnetworkdata senden

Beitrag von RSBasic »

Moxl hat geschrieben:und ich sehe grade das ich nur höchstens 64kb mit einem sendnetworkdata() senden kann (wenn ich mich nich verguckt habe) ... was wenn meine datei größer ist? zB ein bild mit ca 1MB?
Indem du die Dateien in mehreren Paketen sendest und diese beim End-PC empfängst.
Aus privaten Gründen habe ich leider nicht mehr so viel Zeit wie früher. Bitte habt Verständnis dafür.
Bild
Bild
Moxl
Beiträge: 150
Registriert: 26.10.2012 13:19

Re: dateien übers netzwerk via sendnetworkdata senden

Beitrag von Moxl »

ok einfacher gesagt als getan^^ ich hab jetzt keine ahnung wie ich die datei zerlege und in einzelnen paketen sende :/

hmm wenn du vielleicht etwas langeweile hast, kannst du mir eventuell ein ganzen client/server code basteln der leicht zu verstehen ist? :bounce:
denke dann kapier ichs am besten :mrgreen:
Benutzeravatar
HeX0R
Beiträge: 3070
Registriert: 10.09.2004 09:59
Computerausstattung: AMD Ryzen 7 5800X
96Gig Ram
NVIDIA GEFORCE RTX 3060TI/8Gig
Win11 64Bit
G19 Tastatur
2x 24" + 1x27" Monitore
Glorious O Wireless Maus
PB 3.x-PB 6.x
Oculus Quest 2 + 3
Kontaktdaten:

Re: dateien übers netzwerk via sendnetworkdata senden

Beitrag von HeX0R »

Moxl hat geschrieben:hmm wenn du vielleicht etwas langeweile hast, kannst du mir eventuell ein ganzen client/server code basteln der leicht zu verstehen ist? :bounce:
denke dann kapier ichs am besten :mrgreen:
Ja klar :roll:

Es ist ganz simpel:
- Datei mit ReadFile() öffnen.
- 64k-Block mit ReadData() lesen
- 64k-Block mit SendNetworkData() senden (auf Rückgabewert achten!).
- Solange das Ende der Datei nicht erreicht wurde wieder den nächsten 64k-Block mit ReadData() einlesen.
Moxl
Beiträge: 150
Registriert: 26.10.2012 13:19

Re: dateien übers netzwerk via sendnetworkdata senden

Beitrag von Moxl »

so ich bin jetzt soweit eine datei unter 64kb zu senden aber irgendwie kann ich die empfangene datei nicht öffnen... bei einem bild zB kommt immer das die datei evtl beschätigt oder so ist :cry:

hier mal mein code:

Server:

Code: Alles auswählen

      If  serverevent=#PB_NetworkEvent_Data
        clientid=EventClient()
        clientid$=Str(clientid)
        clientip$=IPString(GetClientIP(clientid))
        buffer.s=Space(65536)
        ReceiveNetworkData(clientid, @buffer, 65536)
        crude$=RTrim(buffer.s)
        Select  StringField(crude$, 1, Chr(29))
          Case  "dateisenden"
            dateiname$=StringField(crude$, 2, Chr(29))
            dateigrosse=Val(StringField(crude$, 3, Chr(29)))
            Delay(500)
            *mem=AllocateMemory(dateigrosse)
            ReceiveNetworkData(clientid, *mem, dateigrosse)
            If  CreateFile(0, GetHomeDirectory()+dateiname$)
              WriteData(0, *mem, dateigrosse)
              CloseFile(0)
            EndIf
        EndSelect
        ConsoleColor(2, 0)
        PrintN("Rohdaten von <"+clientid$+"> <"+clientip$+"> empfangen:")
        PrintN(crude$)
        PrintN("")
        ConsoleColor(7, 0)
      EndIf
Client:

Code: Alles auswählen

verbindung=OpenNetworkConnection(host$, port)
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
  input$=Input()
  If  input$<>""
    datei$=OpenFileRequester("", "", "Alle Dateien | *.*", 0)
    If  ReadFile(0, datei$)<>0
      If  Lof(0)=<65536
        *mem=AllocateMemory(Lof(0))
        SendNetworkString(verbindung, "dateisenden"+Chr(29)+GetFilePart(datei$)+Chr(29)+Str(FileSize(datei$)))
        SendNetworkData(verbindung, *mem, Lof(0))
        CloseFile(0)
      EndIf
    EndIf
  EndIf
  ForEver
EndIf
obwohl die neu empfangene datei genau die selbe größe hat :freak:
Moxl
Beiträge: 150
Registriert: 26.10.2012 13:19

Re: dateien übers netzwerk via sendnetworkdata senden

Beitrag von Moxl »

ach ich seh grade ich ich pack beim client die daten von der zusendenden datei nicht in den reservierten speicher sondern ich schicke den leeren speicher mit der länge der zusendenen datei weg... :bluescreen:
Moxl
Beiträge: 150
Registriert: 26.10.2012 13:19

Re: dateien übers netzwerk via sendnetworkdata senden

Beitrag von Moxl »

gut also dateien unter 65kb kann ich jetzt problemlos mit sendnetworkdata() verschicken und empfangen.. aber wie genau mach ich das wenn ich größere dateien verschicken will?
ich weiß zwar das man mehrere kleine pakete unso verschicken soll :cry:

beim client hab ichs jetzt soweit gebracht:

Code: Alles auswählen

verbindung=OpenNetworkConnection(host$, port)
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
  input$=Input()
  If  input$<>""
    datei$=OpenFileRequester("", "", "Alle Dateien | *.*", 0)
    If  ReadFile(0, datei$)<>0
      If  Lof(0)=<65536
        SendNetworkString(verbindung, "dateisenden"+Chr(29)+GetFilePart(datei$)+Chr(29)+Str(FileSize(datei$)))
        *mem=AllocateMemory(Lof(0))
        ReadData(0, *mem, Lof(0))
        SendNetworkData(verbindung, *mem, Lof(0))
        CloseFile(0)
        FreeMemory(*mem)
      Else
        SendNetworkString(verbindung, "grossedateisenden"+Chr(29)+GetFilePart(datei$)+Chr(29)+Str(FileSize(datei$)))
        While Eof(0)
          *mem=AllocateMemory(65500)
          ReadData(0, *mem, 65500)
          SendNetworkData(verbindung, *mem, 65500)
          FreeMemory(*mem)
        Wend
        CloseFile(0)
      EndIf
    EndIf
  EndIf
  ForEver
EndIf
und beim server hab ich kein plan wie ich die einzelnen pakete zusammen fügen soll und woher der server dann weiß wenn das das letzte datenpaket war usw... :freak:

wie schreibt ihr das denn immer wenn ihr große dateien verschicken wollt? :praise:
Antworten