?
Solved

TClientSocket help

Posted on 2004-09-03
14
Medium Priority
?
2,723 Views
Last Modified: 2012-06-27
We are trying to write a program which uses a TClientSocket object to send a text string to an HTTP server and receive the response.

It seems so far that the socket is opened and data is sent to the server (apache logs confirm this). However, no data seems to be recevied and processed on the OnRead event. This does not even seem to be triggered.

Please note that this is Delphi 5.

Code below:

procedure TForm1.BitBtn1Click(Sender: TObject);
begin
Form1.ClientSocket1.Active := True;
//clientsocket1.Open;
clientsocket1.Socket.SendText('GET http://www.getminted.com/Hello HTTP/1.1' + #13 + 'Host: www.getminted.com' + #13 + 'Connection: close' + #13 + #13 );
clientsocket1.socket.
FWaiting := true;
Application.MessageBox('SendText','', MB_OKCANCEL + MB_DEFBUTTON1) ;
while FWaiting do
Application.processmessages;
end;


procedure TForm1.ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);
var
Buffer : array [0..4095] of char;
BytesReceived : integer;
MemoryStream : TMemoryStream;
begin
Application.MessageBox('ClientSocket1Read','', MB_OKCANCEL + MB_DEFBUTTON1) ;

  while FWaiting do
  begin
    MemoryStream := TMemoryStream.Create;
    try
     // Sleep(200);
      while True do
      begin
      BytesReceived := Socket.ReceiveBuf(Buffer,SizeOf(Buffer));
      if (BytesReceived <= 0) then
        Break
      else
      begin
      edit1.text := Buffer;
      MemoryStream.Write(Buffer,BytesReceived);
      end;

      end;
      FWaiting := False;
      MemoryStream.Position := 0;
   // XMLResponse.LoadFromStream(MemoryStream);
    finally
      MemoryStream.Free;
    end;
  end;
end;
0
Comment
Question by:wizard2000
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
14 Comments
 
LVL 2

Expert Comment

by:RHenningsgard
ID: 11973444
If you're getting connected to port 80 of the web server and getting no response to your GET, then your GET isn't formatted correctly.  You may find the easiest way to get it right is to observe in detail how a web browser formats its GET and then duplicate that precisely.

I recommend the following:

1) Get a copy of Ethereal (see http://www.ethereal.com ) and install it on the machine on which you're running your Delphi test application.

2) Run Ethereal, capturing your own network traffic, with the filter "port 80".

3) Use a web browser (like IE) to fetch the URL you're trying to get with your Delphi application.

4) Read the Ethereal log to see precisely how the GET is formatted by IE, then duplicate that precisely in your application.

In the process, you'll both figure out what your application is doing wrong, and you'll learn to use a very powerful diagnostic tool (one you're going to want sooner or later anyhow).

Rob---
0
 
LVL 2

Expert Comment

by:RHenningsgard
ID: 11973467
For what it's worth, I think I've always seen web browsers use both #13 carriage return and #10 line feed for terminators, i.e.

clientsocket1.Socket.SendText('GET http://www.getminted.com/Hello HTTP/1.1' + #13#10 + 'Host: www.getminted.com' + #13#10 + 'Connection: close' + #13#10#13#10 );

That might be the problem.

Rob
0
 
LVL 2

Accepted Solution

by:
RHenningsgard earned 336 total points
ID: 11973529
I just got curious and did what I recommended to you.  Here's what IE did with your test URL.  Note that the URL is "/Hello", not "http://www.getminted.com/Hello" for one thing.

GET /Hello HTTP/1.1
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/msword, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/x-shockwave-flash, */*
Accept-Language: en-us
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; (R1 1.5))
Host: www.getminted.com
Connection: Keep-Alive
Extension: Security/Remote-Passphrase

Rob---
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
LVL 1

Author Comment

by:wizard2000
ID: 11973620
Yep but the thing is, if you do it from a telnet prompt (on a unix machine at least) you get data back. IE just using
GET /Hello HTTP/1.0
Host: www.getminted.com

(note 2 returns to terminate the data)

This returns 'stuff' - thing is im not getting the onread event triggered which as far as im concerned it should be. The additional stuff is not needed to get a response from the server so shouldent be need to trigger the onread as far as i can see.

Why is it not triggering?!?! Driving me nuts... BTW I started using 13 10 as the term chars but it makes no difference.

And, strangest of all, apache is showing the request in the logs. As an error, but a raw socket shouldent be aware of that.
0
 
LVL 1

Author Comment

by:wizard2000
ID: 11973642
Unfortunatly ethereal just crashes as soon as its started...
0
 
LVL 13

Expert Comment

by:BlackTigerX
ID: 11973667
right... you don't send the whole www... after the GET everytime, just the URL from the root point, in this case "/Hello"

in any case... shouldn't you get a response back saying at least error or something?
0
 
LVL 1

Author Comment

by:wizard2000
ID: 11973720
Exactly! Damn event should be triggered... I have a messagebox alert first thing in the onread event but it never gets called, program just gets stuck in the application.processmessages bit.

Normally im a unix / perl coder so this is a bit out of my experience... but do you guys concur this should be right?
0
 
LVL 14

Assisted Solution

by:DragonSlayer
DragonSlayer earned 332 total points
ID: 11987794
I did it the blocking way, and it seems to work:

procedure TForm1.Button1Click(Sender: TObject);
var
  Command: string;
  retBuf: array [0 .. 4095] of Char;
  iReturn: Integer;
begin
  Memo1.Clear;
  with ClientSocket1 do
  begin
    Host := '213.152.247.17'; // www.getminted.com
    ClientType := ctBlocking;
    Port := 80;

    try
      Open;
      Command := 'GET /Hello HTTP/1.1'#13#10 +
        'Host: www.getminted.com'#13#10#13#10;
      iReturn := Socket.SendBuf(Pointer(Command)^, Length(Command));
      if iReturn > 0 then
      begin
        while iReturn > 0 do
        begin
          FillChar(retBuf, SizeOf(retBuf), 0);
          iReturn := Socket.ReceiveBuf(retBuf, SizeOf(retBuf));
          if iReturn > 0 then
            Memo1.Lines.Add(retBuf);
        end;
      end else
        raise Exception.Create('Server not responding!');
    except
      on E: Exception do
        ShowMessage('Error at ' + E.Message);
    end;
  end;
end;




DragonSlayer.
0
 
LVL 1

Assisted Solution

by:mgazza
mgazza earned 332 total points
ID: 12092801
geez iv just wrote thius out once and agen by the looks  why are you using components!!


var
zero:cardinal=0;
procedure HTTPs(URL,Headers:PChar;var OutHeaders, OutDoc:string);

var
  RequestHandle,IOpenHandle : PHandle;
  DataWritten:cardinal;
  buffer:array[0..100] of char;
begin

  IOpenHandle:= InternetOpen('Mozilla/4.0 (compatible)', INTERNET_OPEN_TYPE_PRECONFIG , NIL, NIL, 0);

  // open the file
  RequestHandle:=InternetOpenUrl(iOpenHandle, URL, Headers, length(Headers),
                          INTERNET_FLAG_RAW_DATA or INTERNET_FLAG_SECURE,0);

  if RequestHandle<>nil then begin
   repeat
     if InternetReadFile(RequestHandle,@buffer[0],sizeof(buffer),DataWritten) then
        OutDoc:=OutDoc+copy(buffer,0,DataWritten) else break;
   until DataWritten=0;
   setlength(outheaders,512);
   repeat
    DataWritten:=length(outheaders);
     if HttpQueryInfoA(RequestHandle, HTTP_QUERY_RAW_HEADERS_CRLF, @outheaders[1],DataWritten,zero) then begin
      setlength(outheaders,datawritten);
      break;
     end
     else setlength(outheaders,datawritten*2);
    until datawritten=1024*5;

  end;

  InternetCloseHandle(requestHandle);
  InternetCloseHandle(IOpenHandle);
end;

procedure HTTP(URL,Headers:PChar;var OutHeaders, OutDoc:string);

var
  RequestHandle,IOpenHandle : PHandle;
  DataWritten:cardinal;
  buffer:array[0..100] of char;
begin

  IOpenHandle:= InternetOpen('Mozilla/4.0 (compatible)', INTERNET_OPEN_TYPE_PRECONFIG , NIL, NIL, 0);

  // open the file
  RequestHandle:=InternetOpenUrl(iOpenHandle, URL, Headers, length(Headers),
                          INTERNET_FLAG_RAW_DATA,0);

  if RequestHandle<>nil then begin
   repeat
     if InternetReadFile(RequestHandle,@buffer[0],sizeof(buffer),DataWritten) then
        OutDoc:=OutDoc+copy(buffer,0,DataWritten) else break;
   until DataWritten=0;
   setlength(outheaders,512);
   repeat
    DataWritten:=length(outheaders);
     if HttpQueryInfoA(RequestHandle, HTTP_QUERY_RAW_HEADERS_CRLF, @outheaders[1],DataWritten,zero) then begin
      setlength(outheaders,datawritten);
      break;
     end
     else setlength(outheaders,datawritten*2);
    until datawritten=1024*5;

  end;

  InternetCloseHandle(requestHandle);
  InternetCloseHandle(IOpenHandle);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
Head:Pchar;
d,h:string;
begin

https('https://www.google.com/,nil,h,d);
or
http('http://www.google.com/,nil,h,d);

showmessage(h+d)

end;
0
 
LVL 1

Author Comment

by:wizard2000
ID: 13437522
erm, i accepted an answer days ago... why was this changed?
0

Featured Post

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
This is my first video review of Microsoft Bookings, I will be doing a part two with a bit more information, but wanted to get this out to you folks.
This tutorial will teach you the special effect of super speed similar to the fictional character Wally West aka "The Flash" After Shake : http://www.videocopilot.net/presets/after_shake/ All lightning effects with instructions : http://www.mediaf…
Suggested Courses

777 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question