You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GNAT.SOCKETS.SOCKET_ERROR:[11]排查:Linux下Ada Socket服务端异常

问题排查思路

1. 修复套接字资源泄漏

代码中每次Accept_Socket会生成新的客户端套接字,但未关闭旧套接字。Linux下文件描述符数量有限,多次连接后会耗尽资源触发错误。Windows句柄管理机制更宽松,因此未暴露问题。

  • 解决方案:在处理完客户端请求后(如String'Write之后)添加Close_Socket(Socket);释放资源。

2. 修正套接字超时选项的继承问题

你仅给监听套接字Server设置了Receive_Timeout,但Accept_Socket返回的客户端套接字Socket不会继承该配置。Windows可能隐式继承超时设置,但Linux严格遵循套接字独立性规则,导致客户端套接字无超时限制,在无数据时触发非阻塞类错误。

  • 解决方案:在Accept_Socket后,给Socket也设置相同的Receive_Timeout选项:
    Set_Socket_Option(Socket, Socket_Level, (Receive_Timeout, Timeout => 1.0));
    

3. 定位错误发生的具体步骤

通过异常捕获明确错误是在Accept_Socket还是Character'Read阶段触发,缩小排查范围。修改代码添加异常处理:

loop
   begin
      Accept_Socket(Server, Socket, Address);
      Set_Socket_Option(Socket, Socket_Level, (Receive_Timeout, Timeout => 1.0)); -- 新增超时设置
      receive_str := To_Unbounded_String("");
      Channel := Stream(Socket);
      loop
         begin
            Character'Read(Channel, Receive_Character);
            exit when Receive_Character = '@';
            Append(receive_str, Receive_Character);
         exception
            when GNAT.Sockets.Socket_Error =>
               Put_Line("读取数据时出错: " & GNAT.Sockets.Error_Message);
               raise;
         end;
      end loop;
      Put_Line("ReceiveStr" & To_String(receive_str));
      String'Write(Channel, "OK123");
      Close_Socket(Socket); -- 新增关闭套接字
   exception
      when GNAT.Sockets.Socket_Error =>
         Put_Line("接受连接或处理请求时出错: " & GNAT.Sockets.Error_Message);
         raise;
   end;
end loop;

4. 验证回环地址与端口监听状态

  • 执行ping 127.0.0.2确认Linux系统是否启用该回环地址,部分系统默认未配置额外回环地址可能导致绑定异常。
  • 绑定完成后用netstat -tulpn | grep 65432检查端口是否被正确监听,确认Bind_Socket操作成功。

5. 检查系统资源限制

Linux进程默认文件描述符上限较低(通常为1024),大量并发连接会耗尽资源。执行ulimit -n查看当前限制,临时调整可使用ulimit -n 4096测试,长期调整需修改系统配置文件。

内容的提问来源于stack exchange,提问作者Nessa3001

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 00:20:16