Ada 和 Python 之间的 TCP 套接字

Posted

技术标签:

【中文标题】Ada 和 Python 之间的 TCP 套接字【英文标题】:TCP Socket between Ada and Python 【发布时间】:2021-02-01 17:07:56 【问题描述】:

我真的是 Ada 的新手,想在 Ada 和 Python 之间创建一个 TCP 套接字。 Ada 程序应充当服务器,Python 程序应充当客户端。主要用例是从 Python 接收字符串命令并确认它们的执行。 如果没有 Ada 服务器中的 Ada.Streams.Write(Channel.All, Data);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 一方卡在Ada.Streams.Read 通话中。如果您在发送“Hello, World”后完成 Python 端,它会关闭套接字并且 Ada 端完成读取。在这种情况下,您可能需要逐个字符地读取,直到获得终止符。 【参考方案1】:

事情没有按照您希望的方式进行的原因是您将Receive_Timeout 套接字选项放在Server 套接字上;你需要把它放在 Socket 上,因为那是你接收的套接字。

目前情况:电话

Ada.Streams.Read(Channel.All, Data, Last);

将在读取Data’Length (512) 字节或另一端关闭套接字时终止。

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

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

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


在 macOS 上,Ada 端在 Python 端发送消息后立即打印出它收到的消息。这不是setsockopt() 的手册页所说的回复:SO_RCVTIMEO!在决定放弃之前,它应该等待超时设置(5 秒)。

【讨论】:

以上是关于Ada 和 Python 之间的 TCP 套接字的主要内容,如果未能解决你的问题,请参考以下文章

Python网络编程之TCP网络应用程序开发流程

健壮的连续 TCP 连接(python 套接字)

套接字阻止在 Java 服务器和 Python 客户端之间发送消息

TCP 聊天工具[python]

Socket为啥要翻译成套接字?

Python socket套字节