【发布时间】:2017-02-01 07:23:08
【问题描述】:
我正在使用这个server 从C++ UDP Client 接收几个数据包。
当我需要一个包裹时,我使用Client UDP 发送Request 以让C++ 客户端发送包裹。当我多次执行此过程时,我错过了一些包并收到此错误:
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 ;
【问题讨论】:
-
我完全不明白你为什么有任务;还不如在程序中内联body。拥有一项任务所能做的就是冒着错过预期信息的风险。
Receive_Data是否被不同的端口号调用?因为,如果没有,我会设置一次套接字并将套接字传递给Receive_Data。Integer’Size是 32,也许您想用Offset更新Message_Size! (而Offset将是 8 位字节的数量,无论如何,与Integer无关)。 -
好的抱歉,现在更新了。是的,我使用该函数来调用不同的端口号。
-
也许您应该在请求客户端发送之前准备好接收消息的套接字?而且,将在过程堆栈上声明的数组的地址传递给该过程的调用者是一个非常非常糟糕的主意。
-
我已经尝试在发送请求之前准备好套接字,结果是一样的。这个过程与数据请求的过程一起实现了一个循环,它完美地工作了数百次迭代,但过了一会儿它就失败了。客户端发送最后一个包(我用wireshark检查)但服务器没有读取它。
-
您收到此错误 (
EAGAIN) 是因为您指定了超时并且数据报未在该超时内到达。 UDP 不可靠,数据报可能会丢失,但最可能的原因是客户端在您的服务器完成设置接收它的套接字之前发送了回复。
标签: sockets server udp ada gnat