2016-11-23 80 views
1

我必須從C++客戶端接收UDP數據報。客戶端工作正常,併發送數據報到我編譯此代碼的IP地址。數據報的大小是800Bytes。當我發送數據報時,讀取過程被阻塞。我在這個例子之後創建了這個代碼:https://en.wikibooks.org/wiki/Ada_Programming/Libraries/GNAT.Sockets_examples,這在我的主機上完美工作。任何想法?流讀取阻塞UDP GNAT

procedure RECEIVE_DATA (
         DEST_UDP_PORT  : In WORD_TYPE; 
         SRC_UDP_PORT   : In WORD_TYPE; 
         WAIT_TIME  : In DURATION; 
         MESSAGE_ADDRESS : Out System.Address; 
         WAIT_RESULT  : Out Boolean 
         ) is 

task Receive is 
    entry Start; 
end Receive; 

task body Receive is 
    Address : Sock_Addr_Type; 
    Socket : Socket_Type; 
    Channel : Stream_Access; 
    Receive_Timeout : constant Duration := WAIT_TIME; 
    Offset : Ada.Streams.Stream_Element_Count; 
    Data : Ada.Streams.Stream_Element_Array (1 .. 800); 
begin 
    accept Start; 
    Initialize; 
    WAIT_RESULT := False;  
    Create_Socket (Socket, Family_Inet, Socket_Datagram); 
    Set_Socket_Option (Socket => Socket, 
         Option => (Gnat.Sockets.Receive_Timeout, Timeout => Receive_Timeout)); 

    Address.Addr := Inet_Addr(DEST_UDP_IP); 
    Address.Port := Port_Type(DEST_UDP_PORT); 
    Bind_Socket (Socket, Address); 

    Address.Addr := Inet_Addr(SRC_UDP_IP); 
    Address.Port := Port_Type(SRC_UDP_PORT); 
    Channel := Stream (Socket, Address); 

    loop 
     Ada.Streams.Read (Channel.All, Data, Offset); 
     exit when Offset = 0; 
    end loop; 
    Free (Channel); 
    Close_Socket (Socket); 
    WAIT_RESULT := True; 
    MESSAGE_ADDRESS := Data'Address; 

    exception when E : others => 
     Ada.Text_IO.Put_Line 
     (Exception_Name (E) & ": " & Exception_Message (E)); 
     WAIT_RESULT := False; 
     Free (Channel); 
     Close_Socket (Socket); 
end Receive; 

begin 
    Initialize (Process_Blocking_IO => False); 
    Receive.Start; 
    Finalize; 
end RECEIVE_DATA; 

回答

3

您是否嘗試過使用GNAT.Sockets.Receive_Socket? 流與TCP協同工作,您無法流式傳輸數據報。

例子:

客戶:

with Ada.Streams; 
with Ada.Text_IO; 

with GNAT.Sockets; 

procedure UDP_Client is 
    use GNAT.Sockets; 
    Address : Sock_Addr_Type; 
    Socket : Socket_Type; 
    Data : constant Ada.Streams.Stream_Element_Array (1 .. 512) := (others => 42); 
    Last : Ada.Streams.Stream_Element_Offset; 
begin 
    Address.Port := 50001; 
    Address.Addr := Inet_Addr ("127.0.0.1"); 
    Create_Socket (Socket, Family_Inet, Socket_Datagram); 
    Send_Socket (Socket, Data, Last, Address); 
    Ada.Text_IO.Put_Line ("last :" & Last'Img); 
end UDP_Client; 

服務器:

with Ada.Streams; 
with Ada.Text_IO; 

with GNAT.Sockets; 

procedure UDP_Server is 
    use GNAT.Sockets; 
    Server : Socket_Type; 
    Address, From : Sock_Addr_Type; 
    Data : Ada.Streams.Stream_Element_Array (1 .. 512); 
    Last : Ada.Streams.Stream_Element_Offset; 
    Watchdog : Natural := 0; 
begin 
    Create_Socket (Server, Family_Inet, Socket_Datagram); 
    Set_Socket_Option 
    (Server, 
     Socket_Level, 
     (Reuse_Address, True)); 
    Set_Socket_Option 
    (Server, 
     Socket_Level, 
     (Receive_Timeout, 
     Timeout => 1.0)); 
    Address.Addr := Any_Inet_Addr; 
    Address.Port := 50001; 
    Bind_Socket (Server, Address); 
    loop 
     begin 
     GNAT.Sockets.Receive_Socket (Server, Data, Last, From); 
     Ada.Text_IO.Put_Line ("last : " & Last'Img); 
     Ada.Text_IO.Put_Line ("from : " & Image (From.Addr)); 
     exception 
     when Socket_Error => 
      Watchdog := Watchdog + 1; 
      exit when Watchdog = 10; 
     end; 
    end loop; 
end UDP_Server; 
+0

GNAT.Sockets.Receive_Socket被封鎖只是喜歡閱讀的過程。 –

+0

下面是一個簡單的UDP客戶端/服務器的示例: –

+0

是的。在伯克利套接字術語中,「流」= TCP和「數據報」= UDP。 –