2017-02-01 2 views
0

Я использую это server для получения нескольких пакетов данных от C++UDP Client. Когда мне нужен пакет, отправьте Request с помощью Client UDP, чтобы получить C++ Клиент отправит пакет. Когда я сделать этот процесс несколько раз, я пропустить некоторые пакеты и получить эту ошибку:`GNAT.SOCKETS.SOCKET_ERROR: [11]` Ресурс временно недоступен

GNAT.SOCKETS.SOCKET_ERROR: [11] Resource temporarily unavailable

Я думаю, что может привести, потому что клиент посылает пакет, прежде чем сервер прослушивает, но я не уверен. Есть ли способ его решить? Если это проблема, есть ли способ убедиться, что мой сервер подготовлен до того, как клиент отправит сообщение UDP?

procedure RECEIVE_DATA (
          DEST_UDP_PORT  : In Integer; 
          SRC_UDP_PORT   : In Integer; 
          WAIT_TIME   : In DURATION; 
          MESSAGE_ADDRESS  : Out System.Address; 
          WAIT_RESULT   : Out Integer; 
          MESSAGE_SIZE   : Out Integer 
          ) 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 .. 10000); 

begin 
    Initialize (Process_Blocking_IO => False); 
    WAIT_RESULT := 0; 
    MESSAGE_SIZE := 0; 
    -- Create Socket 
    Create_Socket (Socket, Family_Inet, Socket_Datagram); 
    Set_Socket_Option (Socket => Socket, 
         Option => (Gnat.Sockets.Receive_Timeout, Timeout => Receive_Timeout)); 

    --Bind Address 
    Address.Addr := Inet_Addr(DEFINE_IP_ADDR.IP_BOARD_ADDRESS); 
    Address.Port := Port_Type(DEST_UDP_PORT); 
    Bind_Socket (Socket, Address); 

    Channel := Stream (Socket, Address); 
    -- Receive Socket 
    Ada.Streams.Read (Channel.All, Data, Offset); 

    -- Close socket 
    Free (Channel); 
    Close_Socket (Socket); 
    WAIT_RESULT := 1; 
    MESSAGE_SIZE := Integer(Offset); 
    MESSAGE_ADDRESS := Data'Address; 
    Finalize; 
exception when E : others => 
     Ada.Text_IO.Put_Line 
     (Exception_Name (E) & ": " & Exception_Message (E)); 
     WAIT_RESULT := 0; 
     Free (Channel); 
     Close_Socket (Socket); 
     Finalize;  
end RECEIVE_DATA ; 
+0

Я не понимаю, почему у вас вообще есть задача; может также встроить тело в процедуру. Все, что может сделать задача, - это риск потери ожидаемого сообщения. Вызывается ли «Receive_Data» с разными номерами портов? потому что, если нет, я однажды установил сокет и передал сокет в 'Receive_Data'. 'Integer'Size' - 32, возможно, вы хотите обновить' Message_Size' вместо 'Offset'! (и 'Offset' будет числом 8-битных байтов, так или иначе, с' Integer'). –

+0

Хорошо, извините, теперь он обновлен. Да, я использую функцию для вызова с разными номерами портов. –

+1

Может быть, вы должны подготовить сокет для получения сообщения, прежде чем попросить клиента отправить его? И, это очень очень плохая идея ** передать адрес массива, объявленного в стеке процедуры, вызывающей вызывающей стороне этой процедуры. –

ответ

0

внести следующие изменения

Address.Addr := Inaddr_Any; 

Это адрес, который вы получаете из: не ваш адрес. Укажите свой адрес при отправке и при получении

Смежные вопросы