如何使用Ada正确读写套接字?

5 ada

基本上,我设法将多个客户端连接到一台服务器,但我从服务器读取时出现问题.我有两个任务(线程):一个用于阅读,一个用于写作.

  1. 偏移量永远不会达到0,从而导致无限循环."Incoming > "每次有来自服务器的新传入消息时如何打印?
  2. 我不确定缓冲区大小.我尝试了1..1024但是在服务器发送1024个字符之前没有打印.
  3. 是String'Write一个快捷方式ada.streams.write?

写数据

String'Write(channel, "Hello client");
--Where channel is Gnat.Sockets.Stream_Access type
Run Code Online (Sandbox Code Playgroud)

从服务器读取数据

    task body reader_task is    
      Offset : Streams.Stream_Element_Count;
      Buffer : Streams.Stream_Element_Array (1 .. 1);
   begin
     loop
      Text_IO.put_line("Incoming > "); 
      loop
          Streams.Read (Channel.All, Buffer, Offset);
      exit when offset = 0; 
          for I in Buffer'Range loop
              Text_IO.Put (Character'Val (Buffer (I)));
          end loop;
      end loop;
     end loop;
   end reader_task; 
Run Code Online (Sandbox Code Playgroud)

Sim*_*ght 3

GNAT 套接字是阻塞创建的,因此当您调用时,Streams.Read它将从套接字读取数据,直到

\n\n
    \n
  1. 你的缓冲区已满;或者
  2. \n
  3. 还有\xe2\x80\x99t 尚待读取的字节;或者
  4. \n
  5. 套接字已关闭。
  6. \n
\n\n

在情况 2 中,Read调用会阻塞,直到更多数据到达。只有在情况 3 中,您才会返回未满的缓冲区(在您的代码中,Offset小于Buffer\xe2\x80\x99Last)。

\n\n

如果您有多个客户端,其中任何一个都可能正在发送数据,则可以使用GNAT.Sockets.Check_Selector阻塞,直到其中一个客户端套接字有数据要读取,然后从该套接字读取数据。

\n\n

至于读取完整的输入消息,您可以一次读取一个字节,直到到达终止符(在 HTTP 请求的情况下,这将是双 CR/LF)。当然,你需要与客户端同意什么构成终结者。

\n\n

@ajb 的答案涵盖了写作。

\n