我想写一个程序,应该发送http请求,并从服务器接收整个响应。我还想在Ada流的帮助下做到这一点(不是Send_Socket/Receive_Socket和Stream_Element_Vector和String之间的数据转换)。
我的问题是:如何检测流是否为空?我想这样做是因为当我试图读取比流包含的数据更多的数据时,操作String'Read会自己挂起。我无法确定响应的大小。
目前我的代码是这样的:
with Ada.Text_IO;
with GNAT.Sockets;
with Ada.Strings.Unbounded;
procedure sockets is
package to renames Ada.Text_IO;
package s renames GNAT.Sockets;
package su renames Ada.Strings.Unbounded;
host : constant String := "www.google.pl";
HTTP_PORT : constant s.PORT_TYPE := 80;
task ping is
entry start;
entry stop;
end ping;
task body ping is
query : su.Unbounded_String := su.To_Unbounded_String("");
host2 : su.Unbounded_String;
Address : s.Sock_Addr_Type;
Socket : s.Socket_Type;
Channel : s.Stream_Access;
cr : constant Character := Character'Val(13);
lf : constant Character := Character'Val(10);
new_line : constant String := (cr, lf);
output : String (1 .. 4096);
begin
to.Put("Ala");
to.Put(new_line);
to.Put("Kot");
accept start;
Address.Addr := s.Addresses (s.Get_Host_By_Name (host), 1);
Address.Port := HTTP_PORT;
s.Create_Socket (Socket);
s.Set_Socket_Option (
Socket,
s.Socket_Level,
(s.Reuse_Address, True));
delay 0.2;
to.Put_Line("Lacze z hostem");
s.Connect_Socket(Socket, Address);
Channel := s.Stream (Socket);
to.Put_Line("Wysylam dane");
su.Append(query, "GET / HTTP/1.1");
su.Append(query, new_line);
su.Append(query, "Host: ");
su.Append(query, host);
su.Append(query, new_Line);
su.Append(query, new_line);
String'Write (Channel, su.To_String(query));
to.Put_Line("Odbieram dane");
String'Read (Channel, output);
to.Put(output);
to.Put_Line("Zamykam gniazdo");
s.Close_Socket(Socket);
accept stop;
to.Put_Line("ping stopped");
end ping;
begin
to.Put_Line("Hello World!!!");
ping.start;
ping.stop;
end sockets;
XML/Ada已经包含了从http流中读取文件的实现。看一下input_sources-http文件。
Ada流根据定义是阻塞的。如果你想使用流属性,你必须知道有多少数据到达流。
PS: Black是另一个讨论HTTP的库。