Solved

TClientSocket help

Posted on 2004-09-03
14
2,608 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
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 84 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
 
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
What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

 
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 83 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 83 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

Threat Intelligence Starter Resources

Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

Join & Write a Comment

Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
Here's a very brief overview of the methods PRTG Network Monitor (https://www.paessler.com/prtg) offers for monitoring bandwidth, to help you decide which methods you´d like to investigate in more detail.  The methods are covered in more detail in o…
Polish reports in Access so they look terrific. Take yourself to another level. Equations, Back Color, Alternate Back Color. Write easy VBA Code. Tighten space to use less pages. Launch report from a menu, considering criteria only when it is filled…

759 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

Need Help in Real-Time?

Connect with top rated Experts

26 Experts available now in Live!

Get 1:1 Help Now