Datei lässt sich nicht einlesen übers Internet

Für allgemeine Fragen zur Programmierung mit PureBasic.
Torakas
Beiträge: 63
Registriert: 13.09.2004 09:56

Datei lässt sich nicht einlesen übers Internet

Beitrag von Torakas »

Hi Leute,

ich sitze schon wieder an einem Problem. Ich wuerde gerne ein Bild von einem Apache Server lesen. Dabei will ich nicht die API benutzen oder so.

Hier mal der Beispiel programmcode:

Code: Alles auswählen

; German forum: http://robsite.de/php/pureboard/viewtopic.php?t=2808&highlight=
; Author: dige
; Date: 12. November 2003
Global returnstr.s
Procedure.s HttpPost2(Host.s, url.s, Parameter.s, Port.l, referer.s, cookie.s)
  CRLF.s = Chr(13)+Chr(10)
  
  If Port.l = 0
    Port.l = 80
  EndIf
  
  If FindString(LCase(Host.s), "http://", 0) > 0
    Host.s = ReplaceString(LCase(Host.s), "http://", "")
  EndIf
  
  HTTPHeader.s = "GET " + url.s + " HTTP/1.1" + CRLF.s + "Host: " + Host.s + CRLF.s
  HTTPHeader.s + "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.0; de-AT; rv:1.8a4) Gecko/20040927" + CRLF.s
  HTTPHeader.s + "Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,image/jpeg,image/gif;q=0.2,*/*;q=0.1" + CRLF.s
  HTTPHeader.s + "Accept-Language: de,en;q=0.5" + CRLF.s
  HTTPHeader.s + "Accept-Encoding: identity" + CRLF.s
  HTTPHeader.s + "Accept-Charset: ISO-8859-15,utf-8;q=0.7,*;q=0.7" + CRLF.s
  HTTPHeader.s + "Keep-Alive: 300" + CRLF.s
  If referer.s <> ""
    If FindString(LCase(referer.s), "http://", 0) = 0
      referer.s = "http://"+referer.s
    EndIf
    HTTPHeader.s + "Referer: " + referer.s + CRLF.s
  EndIf
  If cookie.s <> ""
    HTTPHeader.s + "Cookie: " + cookie.s + CRLF.s
  EndIf
  HTTPHeader.s + "Content-Type: application/x-www-form-urlencoded" + CRLF.s
  If Len(Parameter.s) > 0
    HTTPHeader.s + "Content-Length: " + Str(Len(Parameter.s)) + CRLF.s
  EndIf
  HTTPHeader.s + CRLF.s
  
  Request.s = HTTPHeader.s + Parameter.s
  
  ConnectionID.l = OpenNetworkConnection(Host.s, Port.l)
  If ConnectionID.l
    SendNetworkData(ConnectionID.l, Request.s, Len(Request.s))
    
    ContentLength.l = 0 : inschleife.l = Date() : tmpbody.s = "" : tmpheader.s = "" : returnstr.s = "" : header3.s = ""
    Repeat
      Delay(1000)
      tmppuffer.s = Space(61440)
      laenge.l = 0
      NCEvent.b = NetworkClientEvent(ConnectionID)
      If NCEvent.b = 2
        inschleife.l = Date() ; Wenn was kommt, immer wieder zuruecksetzen
        laenge.l = ReceiveNetworkData(ConnectionID, tmppuffer.s, 61440) ; Maximal 60KByte abholen
        Debug Left(tmppuffer.s, laenge.l)
        Debug Len(Left(tmppuffer.s, laenge.l))
        Debug laenge.l
        Debug "-----------------------"
        
        If Len(returnstr.s) + laenge > 61440 
          ; nichts mehr dazuschreiben
          
        Else
          returnstr.s = returnstr.s + Left(tmppuffer.s, laenge.l)
          ;Debug returnstr.s
        EndIf
      EndIf
     
      If FindString(returnstr.s, Chr(13)+Chr(10)+Chr(13)+Chr(10), 0) > 0
        returnstr.s = Mid(returnstr.s, FindString(returnstr.s, Chr(13)+Chr(10)+Chr(13)+Chr(10), 0) + 4, Len(returnstr.s))
      EndIf
      
      If NCEvent.b = 0
        If (Date() - inschleife.l) > 5 ; 2 Sekunden
          ProcedureReturn returnstr.s
          
        EndIf
      EndIf
    ForEver
  Else
    ProcedureReturn ""
  EndIf
EndProcedure

InitNetwork()
HttpPost2("http://www.2homenet.de", "/1.jpg", "", 80, "", "")
CallDebugger

; ExecutableFormat=Windows
; EnableXP
; EOF
Wenn ich jetzt mal das programm starte dann zeigt er mir die Länge der abgerufenen Zeichen, die Zeichen die ausgelesen wurden und wie lange die Zeichenkette ist der ausgelesenen Zeichen ist. Normaler weise sollte das gleich lang sein. ist es aber nicht. wenn ich z.b. das Bild einlese dann hab ich einmal eine angeblich eingelesene Laenge von sagen wir mal 4096 Zeichen aber die laenger die er ausgibt sind aber nur sagen wir mal 34 Zeichen oder so. Da fehlen doch xxxx Zeichen. Das kann doch nicht sein.
Desweitern wenn ich z.b. sage das er immer nur 1 Zeichen lesen soll, dann hat er ab und zu auch den fehler drinne das er angeblich ein Zeichen entfangen hat obwohl eins im String ist.

Wer kann mir helfen, was mache ich falsch. Mit reservierten Speicher habe ich auch schon gearbeitet, aber bringt keine verbesserung.

Wer kann mir helfen. Es ist mir sehr wichtig. 1000 Dank schonmal im voraus.

Gruß,
Torakas
Benutzeravatar
bluejoke
Beiträge: 1244
Registriert: 08.09.2004 16:33
Kontaktdaten:

Beitrag von bluejoke »

In jaPBe ist eine Include enthalten (kann man in den Projekteinstellungen aktivieren) mit der man ganz komfortabel Dateien downloaden kann. Sogar mit Progressbar und so Zeugs. schau am besten in Code, Tips und Tricks per Suche nach GPI, ich weiß den Titel leider nicht mehr.
Ich bin Ausländer - fast überall
Windows XP Pro SP2 - PB 4.00
Benutzeravatar
Laurin
Beiträge: 1639
Registriert: 23.09.2004 18:04
Wohnort: /dev/eth0

Beitrag von Laurin »

HTTP 1.1 erlaubt es Daten in mehreren "schüben" zu übertragen, zB mal 500 Bytes, mal 400 Bytes etc.
In HTTP 1.0 gibt es dieses "Feature" nicht. Dort werden alle Daten immer in einem Rutsch übertragen.
Nimm also 1.0 um dein Problem zu umgehen.

Ein HTTP 1.0 GET Request von mir findest du hier: http://forums.purebasic.com/german/view ... highlight=

Btw: Mit HTTP 1.0 brauch der GET Header nicht so groß zu sein.


Greetz Laurin
Now these points of data make a beautiful line.
And we're out of beta. We're releasing on time.
Torakas
Beiträge: 63
Registriert: 13.09.2004 09:56

Beitrag von Torakas »

Hi,

ich hab jetzt mal auf HTTP 1.0 umgestellt aber trotzdem hab ich keinen Erfolg damit.

Das Bild kommt zwar nicht mehr chunked an aber trotzdem stimmt etwas nicht mit den Daten die ankommen.

Ich habe das Programmteil mal absolut minimiert und es so geschrieben das die ankommenden Daten in eine File geschrieben werden. Rein praktisch muesste ich nur noch den Headerteil aus dem File löschen und es umbenennen zur .jpg und anschauen. es geht aber nicht. Die Daten die ankommen entsprechen nicht den Daten des Files. Nur am anfang und dann wird es anderste.

Hier mal der Programmcode:

Code: Alles auswählen

Procedure.s HttpPost2(Host.s, url.s, Parameter.s, Port.l, referer.s, cookie.s)
  CRLF.s = Chr(13)+Chr(10)
  
  If Port.l = 0
    Port.l = 80
  EndIf
  
  If FindString(LCase(Host.s), "http://", 0) > 0
    Host.s = ReplaceString(LCase(Host.s), "http://", "")
  EndIf
  
  HTTPHeader.s = "GET " + url.s + " HTTP/1.0" + CRLF.s + "Host: " + Host.s + CRLF.s
  HTTPHeader.s + "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.0; de-AT; rv:1.8a4) Gecko/20040927" + CRLF.s
  HTTPHeader.s + "Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,image/jpeg,image/gif;q=0.2,*/*;q=0.1" + CRLF.s
  HTTPHeader.s + "Accept-Language: de,en;q=0.5" + CRLF.s
  HTTPHeader.s + "Accept-Encoding: identity" + CRLF.s
  HTTPHeader.s + "Accept-Charset: ISO-8859-15,utf-8;q=0.7,*;q=0.7" + CRLF.s
  HTTPHeader.s + "Keep-Alive: 300" + CRLF.s
  If referer.s <> ""
    If FindString(LCase(referer.s), "http://", 0) = 0
      referer.s = "http://"+referer.s
    EndIf
    HTTPHeader.s + "Referer: " + referer.s + CRLF.s
  EndIf
  If cookie.s <> ""
    HTTPHeader.s + "Cookie: " + cookie.s + CRLF.s
  EndIf
  HTTPHeader.s + "Content-Type: application/x-www-form-urlencoded" + CRLF.s
  If Len(Parameter.s) > 0
    HTTPHeader.s + "Content-Length: " + Str(Len(Parameter.s)) + CRLF.s
  EndIf
  HTTPHeader.s + CRLF.s
  
  Request.s = HTTPHeader.s + Parameter.s
  
  ConnectionID.l = OpenNetworkConnection(Host.s, Port.l)
  If ConnectionID.l
    SendNetworkData(ConnectionID.l, Request.s, Len(Request.s))
    
    ContentLength.l = 0 : inschleife.l = Date() : tmpbody.s = "" : tmpheader.s = "" : returnstr.s = "" : header3.s = ""
    GesamtLaenge.l = 0 : returnstrLaenge.l = 0 : tmpheaderLaenge.l = 0 : tmpbodyLaenger.l = 0 : chunked.b = #False
    
    ;-
    CreateFile(0, "c:\testjpg.txt") ;-
    ;-
    
    Repeat
      Delay(1)
      tmppuffer.s = Space(61440)
      laenge.l = 0
      NCEvent.b = NetworkClientEvent(ConnectionID)
      
      If NCEvent.b = 0
        If Date() - inschleife.l > 5 ; 6 Sekunden warten bis keine Daten mehr kommen
          CloseFile(0)
          ProcedureReturn returnstr.s
        EndIf
      EndIf
      
      
      If NCEvent.b = 2
        inschleife.l = Date() ; Wenn was kommt, immer wieder zuruecksetzen
        laenge.l = ReceiveNetworkData(ConnectionID, tmppuffer.s, 61440) ; Maximal 60KByte abholen
        
        ; Durchlaufe Byteweise
        *p.BYTE = @tmppuffer.s
        tmplaenge.l = laenge.l
        Debug tmplaenge.l
        While tmplaenge.l
          tmplaenge.l - 1
          WriteByte(*p\b & $FF)
          Debug Str(*p\b & $FF) + " " + Chr(*p\b)
          ;Delay(500)
          
          If returnstrLaenge.l + 1 > 61440
            returnstr.s = Right(returnstr, 61439) + Chr(*p\b)
          Else
            returnstr.s + Chr(*p\b)
            returnstrLaenge.l + 1
          EndIf
          *p + 1
        Wend
        
        
      EndIf
    ForEver
  Else
    ProcedureReturn ""
  EndIf
EndProcedure
InitNetwork()
Aa2.s = HttpPost2("http://www.2homenet.de", "/1.jpg", "", 80, "", "")
CallDebugger
Ich weiss solangsam nicht mehr was ich machen soll. Das HTTP.pbi File was mir bluejoke empfohlen hat kann ich meiner meinung nicht nehmen da ich es universell benutzen will und da muss ich zugriff auf den Header und Cookiedaten haben. Desweitern muss ich diese auch senden koennen in einem Header den ich wegschicke.

Gruß,
Torakas
Antworten