Sockets Ada与Python之间的TCP套接字

Sockets Ada与Python之间的TCP套接字,sockets,ada,Sockets,Ada,我是Ada的新手,我想在Ada和Python之间创建一个TCP套接字。Ada程序应充当服务器,Python程序应充当客户端。主要用例是从Python接收字符串命令并确认它们的执行。 没有Ada.Streams.Write(Channel.All,Data)在Ada服务器和data=s.recv(512)中,至少可以从Python客户端接收Hello World。 我想从Ada服务器向Python客户机发送一个答案,这就是我坚持的地方。我得到一个“套接字错误连接超时”。 Ada服务器: us

我是Ada的新手,我想在Ada和Python之间创建一个TCP套接字。Ada程序应充当服务器,Python程序应充当客户端。主要用例是从Python接收字符串命令并确认它们的执行。 没有
Ada.Streams.Write(Channel.All,Data)
在Ada服务器和
data=s.recv(512)
中,至少可以从Python客户端接收Hello World。 我想从Ada服务器向Python客户机发送一个答案,这就是我坚持的地方。我得到一个“套接字错误连接超时”。 Ada服务器:

   use GNAT.Sockets;
   Server : Socket_Type;
   Socket : Socket_Type;
   Address : Sock_Addr_Type;
   Channel : Stream_Access;
   Data : Stream_Element_Array(1 .. 512);
   Last : Stream_Element_Offset;
   S : Unbounded_String;
begin
   Put_Line("Server Config Started..");
   Create_Socket(Server);
   Set_Socket_Option(Server,
                     Socket_Level,
                     (Reuse_Address, True));
   Set_Socket_Option(Server, Socket_Level,(Receive_Timeout, Timeout => 5.0));
   Bind_Socket(Server, Address => (Family => Family_Inet, Addr => Inet_Addr("127.0.0.2"), Port => 65432));
   Listen_Socket(Server);
   Accept_Socket(Server, Socket, Address);
   Put_Line("Client connected from:" & Image(Address));
   Channel := Stream(Socket);
   Ada.Streams.Read(Channel.All, Data, Last);
   Put_Line("Received:");
   for I in 1 .. Last loop
      Put(Character'Val(Data(I)));
   end loop;
   Ada.Streams.Write(Channel.All, Data);
Python客户端:

HOST = '127.0.0.2'  
PORT = 65432        

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    s.connect((HOST, PORT))
    s.sendall(b'Hello, world')
    data = s.recv(512)
我做错了什么?有人暗示了吗?
提前感谢。

事情没有按您希望的方式发展的原因是您在
服务器上设置了
接收超时
套接字选项;您需要将它放在
套接字上,因为这是您从中接收的套接字

目前的情况是:电话

Ada.Streams.Read(Channel.All, Data, Last);
当它读取了
数据长度
(512)字节或当另一端关闭套接字时终止

在Python脚本末尾包含
data=s.recv(512)
之前,Python正在关闭套接字

现在,它正在等待Ada端将其返回512字节,而Ada端正在等待Python端将剩余的(512-12)字节发送给它。经典的致命拥抱

如何修复?可能的话,让Ada端逐字符读取,直到它读取终止符为止(例如
\0
)。或者你可以使用数据报。在任何情况下,您都需要一个协议来确定线路上的消息边界



在macOS上,只要Python端发送消息,Ada端就会打印出它收到的消息。这不是
setsockopt()
手册页上所说的re:
SO\u RCVTIMEO
!它应该等待设置的超时时间(5秒),然后决定放弃。

Ada端卡在
Ada.Streams.Read
调用上。如果在发送“Hello,World”后完成Python端,它将关闭套接字&Ada端完成读取。在这种情况下,您可能需要逐个字符读取,直到获得终止符。