Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
`GNAT.SOCKETS.SOCKET_错误:[11]`资源暂时不可用_Sockets_Server_Udp_Ada_Gnat - Fatal编程技术网

`GNAT.SOCKETS.SOCKET_错误:[11]`资源暂时不可用

`GNAT.SOCKETS.SOCKET_错误:[11]`资源暂时不可用,sockets,server,udp,ada,gnat,Sockets,Server,Udp,Ada,Gnat,我使用这个服务器从C++UDP客户端接收多个数据包。 当我需要一个包时,我使用客户端UDP发送请求,以获得C++客户端发送包。当我多次执行此过程时,我错过了一些程序包并收到以下错误: GNAT.SOCKETS.SOCKET\u错误:[11]资源暂时不可用 我认为可能是因为客户端在服务器侦听之前发送了包,但我不确定。有办法解决吗??如果这是问题所在,有没有办法确保我的服务器在客户端发送UDP消息之前已准备就绪 procedure RECEIVE_DATA (

我使用这个
服务器
C++
UDP客户端
接收多个数据包。 当我需要一个包时,我使用
客户端UDP
发送
请求
,以获得
C++
客户端发送包。当我多次执行此过程时,我错过了一些程序包并收到以下错误:

GNAT.SOCKETS.SOCKET\u错误:[11]资源暂时不可用

我认为可能是因为客户端在服务器侦听之前发送了包,但我不确定。有办法解决吗??如果这是问题所在,有没有办法确保我的服务器在客户端发送
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 ;

进行以下更改

Address.Addr := Inaddr_Any;

这是您收到的地址:不是您的地址。发送时设置您的地址,接收时设置任何地址

我完全不明白您为什么有任务;也可以在过程中内联主体。拥有一个任务所能做的就是冒着丢失预期消息的风险。
是否接收_数据
是否使用不同的端口号被调用?因为,如果没有,我会设置一次套接字,并将套接字传递给
接收\u数据
Integer'Size
是32,也许您想改为通过
Offset
更新
Message\u Size
!(并且
Offset
将是8位字节数,无论如何,
Integer
没有任何内容)。很抱歉,现在它已更新。是的,我使用这个函数来调用不同的端口号。也许你应该在要求客户端发送消息之前准备好套接字来接收消息?而且,将过程堆栈上声明的数组的地址传递给该过程的调用方是一个非常糟糕的主意。我在发送请求之前尝试准备套接字,结果是一样的。这个过程与请求数据的过程一起被实现成一个循环,它在数百次迭代中完美地工作,但过了一段时间它就失败了。客户端发送最后一个包(我用wireshark检查),但服务器没有读取。您收到此错误(
EAGAIN
),因为您指定了一个超时,并且数据报没有在该超时内到达。UDP不可靠,数据报可能丢失,但最可能的原因是客户端在服务器完成套接字接收设置之前发送了回复。