Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: Fr Jul 04, 2025 19:32

Foren-Übersicht » Programmierung » Allgemein
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 16 Beiträge ]  Gehe zu Seite 1, 2  Nächste
Autor Nachricht
 Betreff des Beitrags: HTTP POST ohne Indy in Delphi
BeitragVerfasst: Fr Feb 06, 2009 10:30 
Offline
DGL Member

Registriert: Mi Nov 12, 2008 18:27
Beiträge: 134
Hallo, ich wollt mal fragen ob jemand von euch schonmal nen

HTTP - POST mit sockets geschrieben hat. nen GET request hab

ich mir grad zusammen gebastelt - code stell ich nachher rein.

ich will halt keine indy komponenten verwenden, da ich damit a) bisher die erfahrung gemacht hab, das es nur in der form klasse funktioniert und b) weils für meine bll ist und ich möglichst keine bibliotheken verwenden möchte

auf wikipedia steht wie nen POST gegliedert sein muss, aber leider kann ich daraus nciht schließen wie das programmtechnisch umgesetzt werden soll. auch das durchstöbern der indy und das extensive googeln hat bis jetzt nur etwas in Java ausgespuckt.

wär nett wenn ihr was helfen könntet.

mfg grey.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Feb 06, 2009 11:34 
Offline
DGL Member

Registriert: So Jun 23, 2002 12:37
Beiträge: 144
Programmiersprache: C/C++, Delphi
Es gibt (zumindest für Windows) die WinInet.pas. Da sind Handle-Typen für Internetobjekte definiert, sowie div. Funktionen zum Initialisieren und Senden von HTTP-Requests.

Du kannst dir damit beispielsweise Handles für deine Verbindung und Session erstellen und mit Funktionen wie InternetOpen(), HttpOpenRequest() bzw. HttpSendRequests deine Daten an einen Webserver schicken. Mit InternetReadFile() kannst du dann auf eine Antwort warten.

Wie das ganze abseits von Windows abläuft oder ob da fertige Bibliotheken zur Verfügung stehen kann ich dir nicht sagen. Das ganze mit einen TCP-Socket quasi von 0 ab an aufzuziehen halte ich (zumindest) für kleinere Projekte für etwas zu umständlich. Das ganze HTTProtokol ist im großen und ganzen doch recht umfangreich.

Viele Grüße


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Feb 06, 2009 17:08 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
Wenn alles nix hilft, lad dir nen Netzwerksniffer (z.B. Wireshark) runter und schau dir an, was der Firefox in solchen Situationen macht. Probiers aber nicht mit zu großen Datenmengen, sonst wird das unübersichtlich ;).

Gruß Lord Horazont

_________________
If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung.
current projects: ManiacLab; aioxmpp
zombofant networkmy photostream
„Writing code is like writing poetry“ - source unknown


„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Feb 06, 2009 22:58 
Offline
DGL Member

Registriert: Mi Nov 12, 2008 18:27
Beiträge: 134
Lord Horazont hat geschrieben:
Wenn alles nix hilft, lad dir nen Netzwerksniffer (z.B. Wireshark) runter und schau dir an, was der Firefox in solchen Situationen macht. Probiers aber nicht mit zu großen Datenmengen, sonst wird das unübersichtlich ;).

Gruß Lord Horazont


schon gemacht ^^ kam nix bei rum - ich bekam als antwort etwas, das ich nicht lesen konnte - opera dagegen schon.


@EnORItZ: Könntest du vielleicht mal nen beispiel posten? - mit wininet hab ich schon mal gearbeitet für nen ftp client, aber ich konnte nix zum HTTP POST finden.

mfg grey


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Feb 06, 2009 23:17 
Offline
DGL Member
Benutzeravatar

Registriert: Di Jul 01, 2003 18:59
Beiträge: 887
Wohnort: (The Netherlands)
Programmiersprache: fpc/delphi/java/c#
Try this: telnet www.domainname.com 80
GET /index.html
Next it either goes to dos/unix again or it list the html code for the page.

Some more info:
http://www.dgate.org/~brg/bvtelnet80/
http://delphi.about.com/od/networking/l/aa112602a.htm (TClientSocket)

_________________
http://3das.noeska.com - create adventure games without programming


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Feb 07, 2009 17:42 
Offline
DGL Member

Registriert: Mi Nov 12, 2008 18:27
Beiträge: 134
also GET hab ich ja schon:

Code:
  1. type test = class(TComponent)
  2.   client: TClientSocket;
  3.   procedure GET;
  4.   procedure clientRead(Sender: TObject; Socket: TCustomWinSocket);
  5.   procedure clientConnect(Sender: TObject; Socket: TCustomWinSocket);
  6.   procedure clientDisconnect(Sender: TObject; Socket: TCustomWinSocket);
  7. end;


Code:
  1. procedure test.GET;
  2. begin
  3. client:=TClientSocket.Create(test1);
  4. client.Port:=80;
  5. client.host:='www.spi3lkind.de'; //<-- Server-IP!
  6. client.OnRead := clientRead;
  7. client.OnConnect := clientConnect;
  8. client.OnDisconnect := clientDisconnect;
  9. client.Open;
  10. end;
  11.  
  12. procedure test.clientRead(Sender: TObject; Socket: TCustomWinSocket);
  13. begin
  14.  form1.Memo1.Text := client.Socket.ReceiveText;´
  15. end;
  16.  
  17. procedure test.clientConnect(Sender: TObject; Socket: TCustomWinSocket);
  18. var
  19. dokument :string;
  20. begin
  21.  dokument := '/';   // das ist die seite die aufgerufen wird - in diesem fall root
  22.  client.Socket.SendText('GET' + ' ' + Dokument + ' ' + 'HTTP/1.0' + #13#10#13#10);
  23.  showmessage('connected');
  24. end;
  25.  
  26.  


war mir jetzt aber fehlt ist die POST funktion mit der man z.b. einen login durchführen kann.


mfg grey


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Feb 07, 2009 19:23 
Offline
DGL Member
Benutzeravatar

Registriert: Di Jul 01, 2003 18:59
Beiträge: 887
Wohnort: (The Netherlands)
Programmiersprache: fpc/delphi/java/c#
Some more info http commands via telnet: http://www.xml.com/pub/a/2004/12/15/telnet-REST.html

_________________
http://3das.noeska.com - create adventure games without programming


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Feb 08, 2009 12:45 
Offline
DGL Member

Registriert: So Jun 23, 2002 12:37
Beiträge: 144
Programmiersprache: C/C++, Delphi
Ich schau mal, wo ichs hab. Dann poste ich es heute gegen Abend.

_________________
--->ladida<---


Zuletzt geändert von EnORItZ am So Feb 08, 2009 20:28, insgesamt 2-mal geändert.

Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Feb 08, 2009 20:00 
Offline
DGL Member

Registriert: So Jun 23, 2002 12:37
Beiträge: 144
Programmiersprache: C/C++, Delphi
Heyho...
Also, im MSDN findet sich schonmal die komplette Referenz zur WinInet-Bibliothek. Die wichtigsten Sachen für dich sind die Http- und Internet-Funktionen. Ich hatte irgendwo ein Beispiel, das Daten via POST an ein PHP Skript gesendet hat, weiß aber leider nicht mehr wo ich das hab :(

In einem Buch hatte ich dieselbe Variante gefunden die du bisher verwendest, mittels TCP eine Verbindung zum Webserver herzustellen, einen String mit den nötigsten Informationen des HTTP Headers zu verschicken und auf eine Antwort zu warten. Da habe ich leider nichts weiter zum Post gefunden, allerdings ist deine bisherige Umsetzung rel. ungünstig, da der Webserver nach jeder Transaktion erstmal die Verbindung zum Client wieder trennt.

Ich habe noch ungefähr den Ablauf mit der WinInet im Kopf, ich versuch das mal zu rekonstruieren:
Mittels der Funktion InternetGetConnectedStatus, kannst du diverse Flags übergeben die dir den Status deiner Internet-Verbindung zurückgeben, sicherlich sinnvoll das anfangs zu überprüfen.

Als nächstes brauchst du drei Handles:
eins für deine Internetverbindung, eins für die Verbindung zum Server und eins für deinen Request (HINTERNET ist der passende Typ aus der WinInet.dcu).
Danach kannst du anfangen deine Verbindung aufzubauen: InternetOpen liefert dir das erste Handle. Die wichtigsten Parameter sind die ersten beiden. Den ersten kannst du nutzen um deine Anwendung beispielsweise als Browser auszugeben ('MSIE compatible' z.b.), der zweite Parameter legt fest ob und wie du einen Proxy nutzen willst (nimm INTERNET_OPEN_TYPE_DIRECT wenn du vom Netzwerk aus surfst und hinter keinm Proxy sitzt, dann holt dein Rechner die passenden IP-Adressen zu angegebenen Hostnamen). Die letzten drei sollten unwichtig sein wenn du keinen Proxy verwendest und dich direkt mit dem Server austauschen willst.
Das zweite Handle bekommst du mittels InternetConnect anhand eines (vorher angeforderten) Handles für deine Internetverbindung und einen String mit der Adresse deines Servers. Die anderen Parameter sind im msdn beschrieben, und eigentlich nicht wirklich erwähnenswert.
Anschließend kannst du ein Opjekt für deinen Request mittels HttpOpenRequest erstellen. Hier legst du dich nun fest wie deine Daten übertragen werden... z.b. PChar('POST') in deinem Fall für den zweiten Parameter. Der dritte Parameter enhält, das Dokument/Skript das du aufrufen willst mit den passend zu übergebenen Werten.
Für die anderen Parameter gibt es vordefinierte Konstanten (wie HTTP_VERSION oder INTERNET_FLAG_NO_AUTH), der Rest kann mit 0 und nil aufgefüllt werden.

Ich hab folgendes nicht getestet, aber im groben könnte ein HTTPReqestOpen so aussehen:
Code:
  1.  
  2. //...
  3. var
  4.   //...
  5.   hInet, hConnect, hRequest: HINTERNET;
  6.   qStr: String;
  7.   //...
  8. begin
  9.   //...
  10.   qStr := 'skript.php';
  11.   hRequest := HttpOpenRequest(hConnect, PChar('POST'), PChar(qStr), HTTP_VERSION, nil, nil, INTERNET_FLAG_NO_AUTH, 0);
  12.   //...
  13. end;


HttpSendRequest() verschickt dann das Objekt hinter deinem Handle. Hier kannst du noch ein par Infos für den Header angeben, allerdings musst du hier auch die Daten festlegen die per POST verschickt werden sollen. Ich glaube es reichte wenn man einen String mit einem Typecast auf PChar übergeben hat, der einfach genauso wie aussah wie bei GET. '?var1=12345&var2=54321' dürfte z.b. schon ausreichen(denke ich).

InternetReadFile() liest hinterher die zurückgegebenen Daten(z.b. vom Skript erzeugten HTML-Code) in einen Puffer.


Wichtig bei der ganzen geschichte ist, dass du ständig mit GetLastError überprüfst, was dir die Funktionen zurückliefern.

Falls du übrigens tiefergehende Infos haben willst zu HTTP und nicht vor langen Texten fürchtest dann schau mal hier rein: http://www.ietf.org/rfc/rfc2616.txt

_________________
--->ladida<---


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Feb 08, 2009 23:11 
Offline
DGL Member

Registriert: Mi Nov 12, 2008 18:27
Beiträge: 134
dank dir vielmals - werds morgen mal ausprobieren und rückmeldung geben


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Feb 09, 2009 18:55 
Offline
DGL Member

Registriert: Mi Nov 12, 2008 18:27
Beiträge: 134
Also ich hab mir folgendes zusammengebosselt:

Code:
  1.  
  2. procedure TForm1.Button1Click(Sender: TObject);
  3. var
  4. content,data : string;
  5.  
  6. accept :  string;
  7. buffer <!-- s:P --><img src=\"{SMILIES_PATH}/icon_razz.gif\" alt=\":P\" title=\"Razz\" /><!-- s:P -->char;
  8. hSession,hConnect,hRequest : HINTERNET;
  9. test:cardinal;
  10. name,passwort :string;
  11. begin
  12.   Name:= 'Loginname';
  13.   Passwort :='Passwort';
  14.   content := 'Content-Type: application/x-www-form-urlencoded';
  15.   data := 'v=2&universe=uni34.ogame.de&login='+Name+'&pass='+Passwort+'&button.x=22&button.y=5';
  16.   accept :='*/*';
  17.   hSession := InternetOpen('MyAgent',INTERNET_OPEN_TYPE_PRECONFIG,nil, nil,0);
  18.   hConnect := InternetConnect(hSession,'http://uni34.ogame.de/',
  19.                               80,nil,nil,INTERNET_SERVICE_HTTP, 0, 1);
  20.   hRequest := HttpOpenRequest(hconnect,
  21.   'POST',
  22.   'game/reg/login2.php',
  23.   nil,
  24.   nil,
  25.   plpstr(accept),
  26.   0,1);
  27.  
  28.  
  29.  
  30.   httpSendrequest(hRequest,pchar(content),length(content),pchar(data),length(data));
  31.   InternetReadFile(hRequest,
  32.   buffer
  33.   ,0,
  34.   test);
  35.   showmessage(string(buffer));
  36. end;


Aber als ausgabe bekomm ich nur kryptische zeichen ... wobei ich auch versucht hab das als utf-8 einzulesen, dann kommt gar nix zurück...


Code:
  1.   showmessage(Utf8ToAnsi(UTF8String(buffer)));



@EnORItZ:wäre toll wenn du ne idee hättest

mfg grey


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Feb 09, 2009 22:14 
Offline
DGL Member

Registriert: So Jun 23, 2002 12:37
Beiträge: 144
Programmiersprache: C/C++, Delphi
Hey!

Passt eigentlich, allerdings solltest du hier den Hostnamen ohne Protokoll angeben..
Code:
  1. hConnect := InternetConnect(hSession,'uni34.ogame.de',80,nil,nil,INTERNET_SERVICE_HTTP, 0, 1);


Für den Buffer solltest du einen Speicherbereich reservieren und mit 0 füllen.
Mit InternetReadfile() kannst du dann solange Chunks einlesen bis lpdwNumberOfBytesRead=0 ist (zwischendurch immer wieder deinen Buffer mit 0 füllen, damit der letzte Chunk nicht noch Daten des alten beinhaltet).

Der Typecast string(buffer) reicht übrigens aus.

Viele Grüße

_________________
--->ladida<---


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Feb 10, 2009 14:45 
Offline
DGL Member

Registriert: Mi Nov 12, 2008 18:27
Beiträge: 134
hmmm .... danke - jetzt verbindet er sich endlich mal :D
aber im InternetReadfile() liegt jetzt der fehler - und ich find nirgends eine gescheite regel wie das jetzt zu benutzen ist, bzw was im msdn steht is ja alles ganz logisch, aber irgendwas muss bei mir da falsch sein.
könntest du vielleicht nen beispielcode posten?

mfg grey


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Feb 10, 2009 20:18 
Offline
DGL Member

Registriert: So Jun 23, 2002 12:37
Beiträge: 144
Programmiersprache: C/C++, Delphi
grey hat geschrieben:
könntest du vielleicht nen beispielcode posten?


Klar :D

Code:
  1.  
  2. const chunksize = 512;                                 //<--neu
  3.  
  4. procedure TForm1.Button1Click(Sender: TObject);
  5. var
  6. content,data : string;
  7.  
  8. accept :  string;
  9. buffer :Pchar;
  10. hSession,hConnect,hRequest : HINTERNET;
  11. bytesread:cardinal;                                           //<--edit
  12. name,passwort :string;
  13. begin
  14.   GetMem(buffer, chunksize);                             //<--neu
  15.   Name:= 'Loginname';
  16.   Passwort :='Passwort';
  17.   content := 'Content-Type: application/x-www-form-urlencoded';
  18.   data := 'v=2&universe=uni34.ogame.de&login='+Name+'&pass='+Passwort+'&button.x=22&button.y=5';
  19.   accept :='*/*';
  20.   hSession := InternetOpen('MyAgent',INTERNET_OPEN_TYPE_PRECONFIG,nil, nil,0);
  21.   hConnect := InternetConnect(hSession,'uni34.ogame.de',                           //<--edit
  22.                               80,nil,nil,INTERNET_SERVICE_HTTP, 0, 1);
  23.   hRequest := HttpOpenRequest(hconnect,
  24.   'POST',
  25.   'game/reg/login2.php',
  26.   nil,
  27.   nil,
  28.   plpstr(accept),
  29.   0,1);
  30.  
  31.  
  32.  
  33.   httpSendrequest(hRequest,pchar(content),length(content),pchar(data),length(data));
  34.  
  35.   //-->neu+edit<--//
  36.   memo1.lines.clear;
  37.   repeat
  38.     FillMemory(buffer,chunksize,0); //0 wegen null-terminiertem string
  39.     InternetReadFile(hRequest,
  40.     buffer,
  41.     chunksize-1,
  42.     bytesread);
  43.     memo1.Lines.Text:=memo1.lines.text+Trim(string(buffer));
  44.   until bytesread = 0;
  45.  
  46.   FreeMem(buffer);
  47.   //-->bis hier<--//
  48. end;
  49.  


Das funktioniert soweit und liefert mir im Memo1 den HTML Code für eine Seite mit der Fehlermeldung von wegen falschem Username oder Passwort.
Zumindest scheinen deine Werte für die zu übergebenen Variablen richtig übergeben zu werden (Im HTML Code stand was vom "Loginname").

Vergiss deine Fehlerverarbeitung mittels GetLastError() übrigens nicht :)

Viele Grüße

_________________
--->ladida<---


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Feb 11, 2009 13:48 
Offline
DGL Member

Registriert: Mi Nov 12, 2008 18:27
Beiträge: 134
Vielen Dank!
Das war _der knackpunkt in meiner BLL, an dem ich gehangen habe, jetzt erst kann ich nämlich all die bereits geschriebenen funktionen testen und wirklich weiter arbeiten!
Vielen vielen Dank! Wenn du magst nenne ich dich Namentlich oder mit Nick in der Danksagung (in die Quelle kommst du sowieso :D )

mfg grey


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 16 Beiträge ]  Gehe zu Seite 1, 2  Nächste
Foren-Übersicht » Programmierung » Allgemein


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.012s | 15 Queries | GZIP : On ]