HTTPRequest für PB umbauen...

Fragen zu allen anderen Programmiersprachen.
Benutzeravatar
Bisonte
Beiträge: 2468
Registriert: 01.04.2007 20:18

HTTPRequest für PB umbauen...

Beitrag von Bisonte »

Ich versuche mich gerade an einen Statsviewer für BF2 und habe einen
open source für die abfrage des gamespyservers in VB gefunden.

Nun hab ich das problem das ich von vb auch nicht den geringsten plan habe...

Code: Alles auswählen

Public Sub sendHTTPrequest(socket As Winsock, item As String, Optional additional As String)
    Dim URL As String

    If (socket.State <> sckConnected) Then
        socket.Connect "bf2web.gamespy.com", 80
        Call updateStatus(frmMain.StatusBar, "Error Sending Data: Socket not connected - reconnecting")
        Exit Sub
    End If

    URL = "GET /ASP/" & item & additional & " HTTP/1.1" & vbCrLf
    URL = URL & "Host: BF2Web.gamespy.com" & vbCrLf & "User-Agent: GameSpyHTTP/1.0" & vbCrLf & vbCrLf

    'frmMain.txtSend.Text = frmMain.txtSend.Text & URL & vbCrLf
    previousHttp = item
    socket.SendData URL
End Sub
Soweit ich das schnalle ist das in PB eine Procedure (Sub-Endsub) nur mit dem Stringaufbau zum senden komm ich nich klar...

könnt da einer aushelfen ?

Edit:
Mich verwirren hauptsächlich die Leerzeichen im URL String....
Ich versuchte es elendlich lange mit dem HTTP-Request von Darkdragon... aber irgendwie klappt das nicht....
PureBasic 6.21 (Windows x86/x64) | Windows11 Pro x64 | AsRock B850 Steel Legend Wifi | R7 9800x3D | 64GB RAM | GeForce RTX 5080 | ThermaltakeView 270 TG ARGB | build by vannicom​​
Benutzeravatar
PMV
Beiträge: 2765
Registriert: 29.08.2004 13:59
Wohnort: Baden-Württemberg

Beitrag von PMV »

Was für Leerzeichen? ... warum verwirren die dich? :?
... das ganze ist in PB noch etwas einfacher, du musst nur mit deinem
Server eine Verbindung aufbauen (OpenNetworkConnection()) ... und
sendest die Strings mittels SendNetworkString().

Dein Url-String, den du senden willst sollte in etwa so aussehen:

Code: Alles auswählen

Url$ = "GET /ASP/" + item$ + additional$ + " HTTP/1.1" + Chr(13) + Chr(10)
Url$ + "Host: BF2Web.gamespy.com" + Chr(13) + Chr(10)
Url$ + "User-Agent: GameSpyHTTP/1.0" + Chr(13) + Chr(10)
Url$ + Chr(13) + Chr(10)
Du sendest deine Daten zeile für Zeile an den Server und mittels der
Leerzeile weis der Server, das keine weiteren Daten kommen.

MFG PMV
alte Projekte:
TSE, CWL, Chatsystem, GameMaker, AI-Game DLL, Fileparser, usw. -.-
Benutzeravatar
AND51
Beiträge: 5220
Registriert: 01.10.2005 13:15

Beitrag von AND51 »

Darüber hinaus würde ich empfehlen, das HTTP/1.0 Protokoll zu verwenden, denn bei 1.1 kann der Server dir die Daten unter Umständen zuerstückelt senden, um seine Auslastung zu verringen.
Als Client hast du dann die Mühe und musst die Daten wieder zusammensetzen.

Schreib in deiner 1. Zeile also besser "HTTP/1.0".

Im übrigen widersprechen sich deine Angaben: Die 1. zeile und User-Agent. Das dürfte aber eigentlich nicht weiter tragisch sein, denn der User-Agent ist bloß die Möglichkeit, Information über die Software mitzugeben, die gerade sendet/empfängt. Die Zeile User-Agent ist sowieso optonal, sie muss nicht zwingend gesendet werden.
PB 4.30

Code: Alles auswählen

Macro Happy
 ;-)
EndMacro

Happy End
Benutzeravatar
PMV
Beiträge: 2765
Registriert: 29.08.2004 13:59
Wohnort: Baden-Württemberg

Beitrag von PMV »

AND51 hat geschrieben:Darüber hinaus würde ich empfehlen, das HTTP/1.0 Protokoll zu verwenden, denn bei 1.1 kann der Server dir die Daten unter Umständen zuerstückelt senden, um seine Auslastung zu verringen.
Als Client hast du dann die Mühe und musst die Daten wieder zusammensetzen.
Was heißt zerstückelt? In jedem fall müssen die empfangenden Daten
vernünftig empfangen und zusammen gesetzt werden, schließlich kann
man nie wissen, wie schnell ein Server senden kann bzw. wie lang das
senden/ empfangen dauert. :wink: Der Server sendet ja nicht zum Spaß
die Zeile "Content-Length" im Header mit :D

Aber das war nicht seine Frage.

MFG PMV
alte Projekte:
TSE, CWL, Chatsystem, GameMaker, AI-Game DLL, Fileparser, usw. -.-
Benutzeravatar
AND51
Beiträge: 5220
Registriert: 01.10.2005 13:15

Beitrag von AND51 »

> Was heißt zerstückelt?
Kennst du das Verfahren "Chunked Encoding" nicht?
Der Server sendet zwar den Header, aber trotzdem kann er z. B. nur die ersten 100 Bytes der Datei senden. Dann hält er zwar die Verbindung aufrecht, aber wartet mit dem weiteren senden von Daten. Wie gesagt, ich vermute, dass der Server seine interne Last somit optimal verteilen will.
Das doofe ist nur, dass vor jedem zerstückelten Block die Längenangabe des jeweiligen Blocks steht. Ein Beispiel:

Code: Alles auswählen

HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 100
Connection: Keep-Alive

[A]
<html>
<he

[5B]
ad>
<title>HTTP/1.1 Chunked Transfer Encoding Beispiel</title>
</head>
<body>
Dieser Datenblock enthält 91 Byte Daten (5B hex = 91 dez)
</body

[9]
>
</html>
Vor jedem Datenblock steht also die Länge in Bytes in hexadezimaler Schreibweise.
Als Anfänger ist es nicht ganz so leicht, man müsste natürlich die Längenangabe herausschneiden, etc. Und was das ganze so schwierig macht ist allein schon die Tatsache, dass man nicht weiß, ob der Server nun "Chunked Encoding" sendet, oder nicht.

> In jedem fall müssen die empfangenden Datenvernünftig empfangen und zusammen gesetzt werden
Nicht ganz. Zwar muss man sich auf "Chunked Encoding" einstellen, weil das bei HTTP/1.1 Standatd ist. Es muss IIRC nicht explizit im Header angegeben werden. Das macht die Sache etwas komplexer.
Und deswegen sage ich, dass es für Anfänger (auch für mich) besser ist, noch HTTP/1.0 zu nehmen.




> schließlich kann man nie wissen, wie schnell ein Server senden kann
Das tut nichts zur Sache. Die Geschwindigkeit wird im Endeffekt vom TCP/IP Protokoll geregelt. Wenn der Emfpänger Daten verwirft, warum auch immer, werden diese neu gesendet. Dabei fällt die Geschwindigkeit ab, denn kurz gesagt funktiniert TCP/IP ja so:
TCP/IP tastet sich an die Geschwindigkeitsgrenze heran. Es fängt langsam an und wird immer schneller, solange bis eine Partei an seine Grenzen stößt oder die Zwischenstationen nicht mehr mitmachen (man spricht dann von einem "Slow Start"). Dann fällt die geschwindigkeit ab, um wieder einen reibungslosen ablauf zu ermöglichen. Dann wirds wieder schneller bis... und so weiter.

> Der Server sendet ja nicht zum Spaß die Zeile "Content-Length" im Header mit
Da hast du Recht. Dennoch auch hier ein kleines "Aber".
Was machst du denn, wenn die Zeile nicht mitgesendet wird? Ich bin mir nicht sicher, aber was, wenn diese Zeile nicht Pflicht ist?
IIRC ist nur die 1. Zeile Pflicht (in HTTP/1.0). Bei HTTP/1.1 hingegen ist auch die Zeile "Host" Pflicht.
In so einer Situation kannst du dich nur auf das (hoffentlich vorhandene) Nullbyte verlassen.


> Aber das war nicht seine Frage.
Und warum diskutierst du dann? :wink: War nurn Scherz!
Du hast Recht, es ist schon wichtig, über sowas hier Bescheid zu wissen.
PB 4.30

Code: Alles auswählen

Macro Happy
 ;-)
EndMacro

Happy End
Benutzeravatar
Bisonte
Beiträge: 2468
Registriert: 01.04.2007 20:18

Beitrag von Bisonte »

Also....

ich mein eigentlich das leerzeichen bei : "GET /ASP/".... damit gehts irgendwie
komplett nicht.


@AND51
Es muss das HTTP/1.1 verwendet werden, da der Server sonst ein Access Denied rausrückt...

bei den anderen versuchen bekomm ich immer ein Length Required zurück.

Wie gesagt es handelt sich um Battlefield 2 Stats die vom GameSpy-Server
geholt werden sollen... der Server ist bei Requests extrem empfindlich, daher
hab ich zumindest im Moment per URLDownloadToFile_ das ganze getestet, und
eigenartigerweise klappts dort sofort.... (seite wird runtergeladen und ich parse das txtfile...)
PureBasic 6.21 (Windows x86/x64) | Windows11 Pro x64 | AsRock B850 Steel Legend Wifi | R7 9800x3D | 64GB RAM | GeForce RTX 5080 | ThermaltakeView 270 TG ARGB | build by vannicom​​
Benutzeravatar
PMV
Beiträge: 2765
Registriert: 29.08.2004 13:59
Wohnort: Baden-Württemberg

Beitrag von PMV »

@AND51
Was meinst du mit Standard? Das es vorzugsweise benutzt wird? Kann
ich mir kaum vorstellen. Oder doch?

Im Endeffekt ist es aber doch nur wichtig, wenn der Server, welchen er
kontaktieren will, das verfahren nutzt. Er möchte ja kein Browser
schreiben, der alle möglichkeiten abdeckt :D ... und nicht jeder Server
akzeptiert noch HTTP1.0 :wink:

@Bisonte: Warum solls mit dem Leerzeichen zwischen "GET" und
"/ASP/..." nicht gehen? GET ist das Befehlswort und das dahinter das,
was du bekommen willst :wink:

MFG PMV
alte Projekte:
TSE, CWL, Chatsystem, GameMaker, AI-Game DLL, Fileparser, usw. -.-
Benutzeravatar
AND51
Beiträge: 5220
Registriert: 01.10.2005 13:15

Beitrag von AND51 »

> Es muss das HTTP/1.1 verwendet werden, da der Server sonst ein Access Denied rausrückt
Ja, dann haben die Entwickler anscheinend Server und CLient exakt aufeinander abgestimmt: Wenn der Request vom Client nicht exakt übereinstimmt dann ist das anfordernde Programm kein Spiel.
Dann nimmste halt HTTP/1.1, da kann man nichts machen.

> bei den anderen versuchen bekomm ich immer ein Length Required zurück
Meine künftige Facharbeit wird sich mit um das HTTP-Protokoll drehen, ich kenne mich schon jetzt bereits mit vielem aus.
Aber mir ist derzeit keine Möglichkeit bekannt, anzugeben, wie viel Daten man erhalten möchte; das heißt doch.
Mit "Range". Ohne diesem Schlüsselwort gäbe es keine Downloadmanager.
Mit Range kann man bestimmen, welche Daten einer Datei man haben möchte, es funktioniert genauso wie FileSeek():

Code: Alles auswählen

GET /bla.htm HTTP/1.1
Host: www.and51.de
Range: 0-51, 91-100, 194-
Connection: Close
Hier werden von der Datei 'bla.htm' die ersten 52 Byte angefordert (Zählung beginnt bei 0), dann noch die Bytes 92-101 und schließlich alle Bytes ab dem 195 Byte bis zum Ende der Datei.

Ich bin mir gerade nicht sicher, ob das Schlüsselwort nun "Range" oder "Byte" heißt, denn:
Man kann mit "HEAD" oder "OPTIONS" anstatt "GET" oder "POST" schon abfragen, welche Dinge ein Client mit der Datei anstellen kann.
Ich glaube OPTIONS gibt mehr Infos. Sendest du einen OPTIONS-Request, sagt dir der Server beispielsweise, ob man die Datei teilweise herunterladen darf.
Das sieht dann so aus:

Code: Alles auswählen

OPTIONS /bla.htm HTTP/1.1
Host: www.and51.de (Host ist Pflicht in HTTP/1.1)
Nein, ich habe hier kein CONNECTION vergessen. beim Weglassen wird der Standardwert benutzt. Der Standardwert wäre in HTTP/1.0 "CLOSE", in HTTP/1.1 ist er "KEEP-ALIVE".

Eine Antwort könnte so aussehen:

Code: Alles auswählen

HTTP/1.1 200 OK
Allowed: GET, POST, HEAD, OPTIONS
Accept-Range: Byte
E-Tag: asdfasdf-and51-qwertz
ACCEPT-RANGE bedeutet, dass es erlaubt ist, diese Datei teilweise mit RANGE bzw. BYTE (ich weiß gerade das korrekte Schlüsselwort von beiden nicht) herunterzuladen. Läd man eine Datei teilweise herunter, ist der Statuscode nicht "200 OK", sondern "206 Partial Content".


Soviel dazu.



> hab ich zumindest im Moment per URLDownloadToFile_ das ganze getestet, und eigenartigerweise klappts dort sofort....
Dann biege doch mal URLDownloadToFile_() um, das mach ich auch immer. Schnapp dir das Network-Server Beispiel aus der Hilfe, ändere den Port auf 80 und versuche mit einem 2. Code mal folgende Datei zu laden: "http://localhost/bla.htm"
Dann wird der Request, den der Befehl an deinen eigenen Server schickt, debuggt.
Nun kannst du diesen Request abschreiben und selbst benutzen.

> der Server ist bei Requests extrem empfindlich
Wie ich schon ganz oben schrieb, vermute ich, dass der Grund ist, dass nur Requests von eigenen Produkten akzeptiert werden sollen.

> Was meinst du mit Standard? Das es vorzugsweise benutzt wird?
Mit "Standard" meinte ich nur, dass "Chunked Encoding" vom Server ohne Vorwarnung/Hinweis eingesetzt werden kann. Kann... muss aber nicht.
Wie gesagt, diese Technik gibt es eigentlich erst seit HTTP/1.1, daher habe ich empfohlen, HTTP/1.0 zu benutzen.
Ich mache das aus diesem Grund auch so bei meinen Projekten. Noch ist HTTP/1.0 nicht zu alt/altmodisch/überholt/outdated/depreciated/suchdirwasaus.


> Im Endeffekt ist es aber doch nur wichtig, wenn der Server, welchen er
kontaktieren will, das verfahren nutzt.
Ich kann auch einen eigenen Webserver schreiben (was ich mal vorhatte und immer noch vorhabe), welcher das HTTP/1.1 Protokoll unterstützt. Aber weißt du dann, ob meiner es auch einsetzen wird?
Das kannst du als Außenstehender nicht wissen, bis du es getestet hast. Ebenso kann Bisonte das nicht wissen.

> Er möchte ja kein Browser schreiben, der alle möglichkeiten abdeckt
Das ist richtig. Es ist aber schon wichtig zu prüfen, ob grobe Fehler auftreten. Für projekte wie seines halte ich es für wichtig, zumindest zu prüfen, ob der Statuscode <>200 ist, denn in diesem Fal ist was schief gelaufen. Von URLDownloadToFile_() halte ich im Übrigen selber nicht viel, aus mindestens 2 Gründen:
1. IIRC erscheint die angegebene URL im Brwoserverlauf oder in sonstigen Windows-Histories.
2. Dieser Befehl funktioniert nur auf wenigen Rechnern und mit bestimmten Servern.
Warum weiß ich auch nicht, aber ich kann z. B. google.de abfragen, meinen eigenen Webspace damit jedoch nicht.

> und nicht jeder Server akzeptiert noch HTTP1.0
Sollte er aber, weil HTTP/1.0 noch nicht so überholt ist, wie HTTP/1.1.
Meiner Meinung nach akzeptieren noch genügend Server HTTP/1.0, aber dieser Punkt, ist IMGO einer, über den man sich streiten kann.

> GET ist das Befehlswort
Befehlswort? Wie sagt man? Richtig, "Danke"!
Richtiger wäre ein Ausdruck wie "Methode" in Anspielung auf das METHOD-Attribut beim HTML-Tag FORM.
Alternativ könnte man es aber auch sowas wie "Optionswort" oder "Anforderungsart" nennen.
Unter einem "Befehlswort" stelle ich mir eher sowas wie "GIVEME" vor... :lol:
Herrlich, PMV, das hat mir einen schönen Lacher beschert! :allright:
PB 4.30

Code: Alles auswählen

Macro Happy
 ;-)
EndMacro

Happy End
Benutzeravatar
PMV
Beiträge: 2765
Registriert: 29.08.2004 13:59
Wohnort: Baden-Württemberg

Beitrag von PMV »

Na da will aber einer heute hoch hinaus :? ... kannst froh sein das ich
aktuell keine Lust auf das hab, wa sich eigentlich tun sollte ^_^ ...

... sonnst würd ich mich nicht drauf einlassen ... schließelich schießt du
grad meilen weit am Ziel vorbei. :wink: ... Die Frage war lediglich, wie er
einen vernünftigen Http-Get-Request senden kann. (so viel zum Thema
Befehlswort, Methode oder was du auch immer da zu sagen willst :lol: )
... über das Empfangen der Antwort ist er noch garnicht eingegangen.
Vielleicht schaft er das ja auch ganz alleine durch rumprobieren :wink:

... Ich wiederhole noch mal: Es geht hier nicht um einen Browser-Client,
der sämtliche möglichkeiten abdeckt. Genau so geht es nicht zwingend
um einen Standart-Http-Server, der sämtliche Protokoll-Eigenschaften
kann. Er möchte nur den Status von BF2-Accounts erhalten, nicht mehr,
und nicht weniger. Wenn ich deine Posts so lese, hab ich das gefühl, jeder
Server müsste jede kleinichkeit kennen, nur weil er ein wenig auf dem
HTTP-Protokoll aufbaut. Leg mal nen Gang tiefer ein :D

... ach ja
Ich kann auch einen eigenen Webserver schreiben (was ich mal vorhatte und immer noch vorhabe), welcher das HTTP/1.1 Protokoll unterstützt. Aber weißt du dann, ob meiner es auch einsetzen wird?
Das kannst du als Außenstehender nicht wissen, bis du es getestet hast. Ebenso kann Bisonte das nicht wissen.
Wenn an dem Server eine Anfrage sendet, wird er Antworten. Dann weis
man, womit der Server antworten wird bei dieser Anfrage. Das Verhalten
ändert sich nicht nach nem Zufallsverfahren und somit kann man davon
ausgehen, dass der Server in diesem Fall immer das entsprechende
sendet. Für etweilige änderungen gibs Updates :wink: ... aber wenn jeder
wegen eines kleinen Tools gleich den kompleten HTTP-Standard
unterstützen müsste ... *lol* :lol: ... wie is das mit den Kanonen und den
Spatzen?

Noch mal zum Befehlswort: Ob Methoden-Name, Prozedur-Name,
Befehlswort, Attributbezeichnung oder was auch immer ... Synonyme.
Wobei, wenns dich belustigt ... soll mir auch recht sein, bin ja nen lustiger
Typ :mrgreen:

MFG PMV
alte Projekte:
TSE, CWL, Chatsystem, GameMaker, AI-Game DLL, Fileparser, usw. -.-
Benutzeravatar
AND51
Beiträge: 5220
Registriert: 01.10.2005 13:15

Beitrag von AND51 »

> Na da will aber einer heute hoch hinaus
> Leg mal nen Gang tiefer ein
Ich glaube, du hast Recht. :|
Ich tu das mal eben... Klack! :)

> Wobei, wenns dich belustigt ... soll mir auch recht sein, bin ja nen lustiger Typ
Ja, das bist du! <)
Wollte damit nicht über dich lachen, sondern das hat mich zum Lachen gebracht.

@ Bisonte:
Wie gesagt, probier mal aus, URLDownloadToFile_() auf deinen eigenen Server umzubiegen, dann dürftest du eigentlich einen HTTP-Request erhalten, welchen du für dein Programm verwenden kannst. Wie ich in meinem obigen Post beschrieben habe.

@ PMV:
Das da --------------------------------------^
waren aber jetzt mindestens 2 Gänge, oder? :allright:
PB 4.30

Code: Alles auswählen

Macro Happy
 ;-)
EndMacro

Happy End
Antworten