Re: GNAT.Sockets. Blocking?



I have a couple of programs that preform this type of task.

First, web pages begin with "<html>" and normally end with "</html>".
Second, each server can be set to use a block size for the page that may be
256B, 1KB or 4KB. But in some rare cases the server can use odd sizes. Use
the unsecure "Telnel <server web page>:80" to see what info you will need to
process.

Also, some servers (Like the Microsoft Servers) to prevent robot or programs
like this, request some browsers information or they close the connection.
And some servers or web pages like 'google" use cookies. And for some server
that have Ads, if these are not downloaded and a cookie set can block the
complete page from be transmitted.

And if you play with 'PingPong" a program commented in GNAT.Sockets
specification file (g-socket.ads) you will se that if you alter the string
size it will cause the prograsm to block.


A basic outline for this type of program is:

<<Routine>> Get_String -- Reads a set characters and build a string
-- from socket

<<Routine>> Get_Web_Page -- Read a Web page from the net
...
Line := 1 ;
Open connection
loop
Input := Get_String
until Input = "<html>" loop -- Should be first string

Page ( Line ) := Input
Line := Line + 1 ;

while Input /= "</html>" loop -- Should be last string
Input := Get_String
Page ( Line ) := Input
Line := Line + 1 ;
end loop

Close connection
...
return Page -- At this point Page is array of variable lengths
-- strings that contains => "<html>" ... "</html>"

exception
when Socket_Error => -- Server close connection
-- Process corrupted page???

when Timeout => -- May be needed if Server stop transmitting
close connection
-- Process corrupted page???


In <158756da-21b7-4e2d-b288-7ba030f1f35c@xxxxxxxxxxxxxxxxxxxxxxxxxxx>, "Jacob M. H. Smith" <jacob.m.h.smith@xxxxxxxxxxxxxx> writes:
Hi,

I'm kind of new to socket programming and I need some help here. I
wrote a simple little program that just fetches Google's index page.
The posted code works, but only because I used a "Connection: close"
header in the HTTP request. How would set up my code responsible for
reading the data from the stream so that I can read the page while
keeping the connection open? If I remove the header the program seems
to stop when calling the Ada.Streams.Read function if there is less
than BUFFER_SIZE data in the streams buffer. Can't I just read as much
as is available?

Thanks in advance.

Here's the code:

-------------------

with Ada.Text_IO;
with Ada.Streams;
with GNAT.Sockets;

procedure Socket_Test is

procedure Connect (
Socket : out GNAT.Sockets.Socket_Type;
Channel : out GNAT.Sockets.Stream_Access;
Host : in String;
Port : in GNAT.Sockets.Port_Type) is
HOST_ENTRY : constant GNAT.Sockets.Host_Entry_Type :=
GNAT.Sockets.Get_Host_By_Name (Host);
Address : GNAT.Sockets.Sock_Addr_Type;
begin
-- Prepare the address structure. TODO: make a loop
Address.Addr := GNAT.Sockets.Addresses (HOST_ENTRY, 1);
Address.Port := Port;
-- Set up the connection.
GNAT.Sockets.Create_Socket (Socket);
GNAT.Sockets.Connect_Socket (Socket, Address);
Channel := GNAT.Sockets.Stream (Socket);
-- TODO: error handling.
end Connect;

use type Ada.Streams.Stream_Element_Count;

BUFFER_SIZE : constant Ada.Streams.Stream_Element_Count := 256;
HTTP_PORT : constant GNAT.Sockets.Port_Type := 80;
CRLF : constant String := (ASCII.CR, ASCII.LF);
HOST : constant String := "www.google.com";

Socket : GNAT.Sockets.Socket_Type;
Channel : GNAT.Sockets.Stream_Access;
Byte_Count : Ada.Streams.Stream_Element_Count;
Buffer : Ada.Streams.Stream_Element_Array (1 .. BUFFER_SIZE);

begin

-- Initialize.
GNAT.Sockets.Initialize;

-- Connect.
Connect (Socket, Channel, "www.google.com", HTTP_PORT);

-- Send HTTP request.
String'Write (Channel,
"GET / HTTP/1.1" & CRLF &
"Host: " & HOST & CRLF &
"Connection: close" & CRLF &
CRLF);

-- Read incoming data.
loop
Ada.Streams.Read (Channel.all, Buffer, Byte_Count);
exit when Byte_Count = 0;
for I in 1 .. Byte_Count loop
Ada.Text_IO.Put (Character'Val (Buffer (I)));
end loop;
end loop;

end Socket_Test;

.



Relevant Pages

  • Re: Problem with OnReceive method
    ... > I' m developing a multithread application with a socket network ... > continuosly Receive in the thread socket loop. ... > this one start the server thread. ... when a connection arrived it start a new childthread and ...
    (microsoft.public.vc.mfc)
  • DNS Errors ?
    ... We have a VB.NET 2.0 application running as a service on several servers. ... domain admin acct. ... or established connection failed because connected host has failed to ... Socket s4, Socket s6, Socket& socket, IPAddress& address, ConnectSocketState ...
    (microsoft.public.dotnet.general)
  • Re: tcp connection in gui: event based
    ... Write a small proc that does the accept and sets the connection to ... Use to register procs that get fired when the socket is ... If you have a full line, send it to the GUI, maybe dispatching via ... after to not block the event loop if its a bit bigger ...
    (comp.lang.tcl)
  • Re: TCP Sockets errors
    ... connected socket?", you'd put the read code, GetString, and Invoke in a loop ... to the outer loop waiting for another connection. ...
    (microsoft.public.dotnet.framework.compactframework)
  • Re: Clarification please
    ... Sorry writing the last post i did figure out the answer, in my loop as i ... read the string i escape the loop on reading a 0, ... > connection, send data, close the socket and repeat. ...
    (microsoft.public.win32.programmer.networks)