JNA 调用 SetTcpEntry 总是返回 317

Posted

技术标签:

【中文标题】JNA 调用 SetTcpEntry 总是返回 317【英文标题】:JNA call SetTcpEntry always returning 317 【发布时间】:2021-11-10 15:09:50 【问题描述】:

我目前正在编写一个测试/模拟软件,该软件将使用专有 TCP/IP 协议模仿通信客户端的某种行为。为了模拟断开的连接,我只想将打开的客户端套接字踢出列表。经过一些研究,我发现 iphlpapi 中的 SetTcpEntry 方法是执行此操作的候选方法。 我已经使用 JNA 在 Java 中成功实现了这种方法。但是,即使我以管理员身份运行我的模拟软件,SetTcpEntry 调用也会返回 317。从它的文档中我发现这表明程序正在以非提升的方式运行。但是从其他一些doc 中阅读,它解释了如何手动检查 UAC 提升,我知道程序正在提升运行。 有没有人对这种电话有类似的问题?我该如何解决这个问题?也许还有其他方法可以摆脱我的套接字。

为了完整起见,这是删除套接字的 Java 代码:

    public static boolean killSocket(final iosession p_ioSession)
    
        LogMF.info(LOGGER, "Attemtping to delete TCP connection 0 - 1", p_ioSession.getLocalAddress(), p_ioSession.getRemoteAddress());

        final MIB_TCPROW.ByReference entry = new MIB_TCPROW.ByReference();
        entry.dwLocalAddr.setValue(CodecUtil.getInt(CodecUtil.skipOrder(((InetSocketAddress) p_ioSession.getLocalAddress()).getAddress().getAddress())));
        entry.dwLocalPort.setValue(htons(((InetSocketAddress) p_ioSession.getLocalAddress()).getPort()));
        entry.dwRemoteAddr.setValue(CodecUtil.getInt(CodecUtil.skipOrder(((InetSocketAddress) p_ioSession.getRemoteAddress()).getAddress().getAddress())));
        entry.dwRemotePort.setValue(htons(((InetSocketAddress) p_ioSession.getRemoteAddress()).getPort()));
        entry.state.State = MIB_TCP_STATE_DELETE_TCB;
        entry.state.setType("State");

        final int ret = library.SetTcpEntry(entry).intValue();

        if (ret == 0)
        
            LogMF.info(LOGGER, "TCP connection 0 - 1 marked deleted", p_ioSession.getLocalAddress(), p_ioSession.getRemoteAddress());
            return true;
        

        switch (ret)
        
            case ERROR_ACCESS_DENIED:
                LogMF.error(LOGGER, "Failed to delete TCP connection 0 - 1: Access is denied. Run as administrator.",
                        new Object[]  p_ioSession.getLocalAddress(), p_ioSession.getRemoteAddress() );
                break;
            case ERROR_NOT_SUPPORTED:
                LogMF.error(LOGGER, "Failed to delete TCP connection 0 - 1: IPv4 is not configured.", new Object[]  p_ioSession.getLocalAddress(), p_ioSession.getRemoteAddress() );
                break;
            case ERROR_INVALID_PARAMETER:
                LogMF.error(LOGGER, "Failed to delete TCP connection 0 - 1: Invaid function argument", new Object[]  p_ioSession.getLocalAddress(), p_ioSession.getRemoteAddress() );
                break;
            case ERROR_NOT_ELEVATED:
                LogMF.error(LOGGER, "Failed to delete TCP connection 0 - 1: Running unelevated.", new Object[]  p_ioSession.getLocalAddress(), p_ioSession.getRemoteAddress() );
                break;
            default:
                LogMF.error(LOGGER, "Failed to delete TCP connection 0 - 1: Unknown error.", new Object[]  p_ioSession.getLocalAddress(), p_ioSession.getRemoteAddress() );
                break;

        

        return false;
    

【问题讨论】:

在其他地方的搜索表明,如果套接字不存在(文档中没有,但显然是这种情况)并且错误代码不可靠,您可以获得 317。有这种可能吗? @DanielWiddis 感谢您的提示。我自己也遇到过这个(见下面我的回答)。这只是关于我认为的文档, 【参考方案1】:

好的,返回码有误导性。 实际问题是我对 htons 的实现。在通过 JNA 使用本机实现之后,问题就消失了,并且在运行提升时给出了功能。

【讨论】:

以上是关于JNA 调用 SetTcpEntry 总是返回 317的主要内容,如果未能解决你的问题,请参考以下文章

找不到使用 JNA 调用的 DLL 所需的文件

如何使用 JNA 读取 Linux 命令的输出

JNA ByteBuffer statvfs

无法使用 JNA 找出本机类型的映射

JNA调用DLL简单使用

java使用JNA框架调用dll动态库