J'utilise ce server
pour recevoir plusieurs paquets de données d'un C++
UDP Client
. Lorsque j'ai besoin d'un paquet, j'envoie un Request
en utilisant un Client UDP
pour que le client C++
envoie le paquet. Quand je fais ce processus plusieurs fois, je manque certains paquets et cette erreur:`GNAT.SOCKETS.SOCKET_ERROR: [11]` Ressource temporairement indisponible
GNAT.SOCKETS.SOCKET_ERROR: [11] Resource temporarily unavailable
Je pense que peut causer parce que le client envoie le paquet avant que le serveur est à l'écoute, mais je ne suis pas sûr. Y a-t-il un moyen de le résoudre? Si c'est le problème, est-il possible de s'assurer que mon serveur est préparé avant que le client envoie le message 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 ;
Je ne comprends pas pourquoi vous avez une tâche du tout; pourrait aussi bien intégrer le corps dans la procédure. Tout ce qu'une tâche peut faire, c'est courir le risque de manquer le message attendu. Est-ce que 'Receive_Data' est appelé avec des numéros de port différents? parce que, sinon, je configurerais le socket une fois et passerais le socket à 'Receive_Data'. 'Integer'Size' est 32, peut-être que vous voulez mettre à jour' Message_Size' par 'Offset' à la place! (et 'Offset' sera le nombre d'octets de 8 bits, de toute façon, rien à faire avec' Integer'). –
Ok désolé, maintenant il est mis à jour. Oui, j'utilise la fonction pour être appelé avec des numéros de port différents. –
Peut-être que vous devriez préparer le socket pour recevoir le message avant de demander au client de l'envoyer? Et, c'est une ** très très mauvaise idée ** de passer l'adresse d'un tableau déclaré sur la pile d'une procédure à l'appelant de cette procédure. –