我应该关闭tcp连接吗?

Posted

技术标签:

【中文标题】我应该关闭tcp连接吗?【英文标题】:Should I close the tcp connection? 【发布时间】:2018-07-02 16:33:16 【问题描述】:

我有一个 Java 打印应用程序,它使用原始 TCP 套接字将票据打印到网络打印机。此应用程序是一个 REST 侦听器,当它接收到命令时,它会使用与单个以太网热敏打印机的单个连接进行打印。

这是我的单例服务使用的代码:

public class TcpPrinterWrapper implements PrinterWrapper 

    private static Logger log = LoggerFactory.getLogger(TcpPrinterWrapper.class);

    private PrinterOpzioni opzioni;
    private TcpWrapper wrapper;


    public TcpPrinterWrapper(PrinterOpzioni opzioni) 
        super();
        this.opzioni = opzioni;
        wrapper=new TcpWrapper();
    



    @Override
    protected void finalize() throws Throwable 
        if(wrapper!=null) trywrapper.close();catch (Exception e) 
        super.finalize();
    


    private void openPort()
        try 
            if(wrapper==null)
                wrapper=new TcpWrapper();
            wrapper.openPort(opzioni, opzioni.getTcpTimeout());
         catch (Exception e) 
            log.error("Errore apertura porta",e);
            throw new HardwareException("Porta stampante non valida o non disponibile");
        
    

    @Override
    public synchronized void print(byte[] content, boolean close) throws Exception 
        try
            if(wrapper==null || !wrapper.isOpened())
                openPort();
            
            wrapper.write(content);
            if(close)
                close();
        catch(Exception e)
            try
                wrapper.close();
            catch(Exception e1)
            throw e;
        
    

    @Override
    public void close()
        try 
            wrapper.close();
            wrapper=null;
         catch (Exception e) 
    


我的问题是:它是否应该在每次打印结束时关闭其套接字 工作?还是 TCP 套接字可以保持打开数小时等待作业?

我不知道 REST 请求的频率,但我确信他们可以等待很多小时,但也可以在一分钟内调用很多。这就是为什么我不能回答,一个套接字可以保持打开等待这么久吗?另一方面,我可以在几分钟内打开/关闭/打开/关闭许多套接字吗?我应该使断开连接计时器复杂化吗?

【问题讨论】:

是否应该在每个打印作业结束时关闭其套接字? - 是否正在建立多个套接字连接,或者,它是否只是一个继续提供打印的连接工作? 现在我只有一个连接,但我不能说是应该在每次打印作业后关闭它还是只关闭进程。 投反对票的人能否给出理由? @Tobia - 我还不清楚。如果您只有一个连接,那么如何在不影响进程的情况下关闭它?您能否进一步澄清一下流程(在您的上下文中)是什么意思? @Am_I_Helpful 我重写了这个问题,如果现在清楚了,请告诉我。谢谢 【参考方案1】:

您没有使用原始套接字(不可能使用现有的 Java 网络标准包;您需要在 JNI 的帮助下使用本机调用来使用原始套接字)。

您在代码中使用的似乎是具有从 Java 标准包的 TCP 套接字扩展而来的 TCPSocket 的打印服务器。而且,还有太多代码没有共享。

我的问题是:它是否应该在每次打印结束时关闭其套接字 工作?还是 TCP 套接字可以保持打开数小时等待作业?

理想情况下,每个应用程序都应该有进程超时,或者在一定时间后释放资源。在请求等待的情况下关闭会话是安全(和最佳实践)的一般原则。通过进程,我的意思是如果不使用底层资源,则应关闭连接或/并给出超时(取决于应用程序的用例)。

所以,是的,如果类TcpWrapper 扩展类Socket,你应该设置连接超时以及读取超时。最重要的是:“一旦操作完成,你应该关闭客户端和服务器端的Socket”。

您可以利用 Socket 池来管理您的打印应用程序的多个连接,如 Manage Client Socket Pool 帖子中所述。

【讨论】:

感谢您的回答,我写了“原始套接字”来解释与打印机的连接不是共享打印机作业,而是向打印机发送字节的套接字连接。例如,我可以使用带有“原始”连接的腻子客户端进行打印。显然我正在使用 Java 库的 Tcp 包装器。 @Tobia - 您对此还有什么疑问吗?如果有什么不清楚的地方,我想进一步澄清。 我决定在每次工作后关闭它。如果有两个后续打印,可能会有一些开销重新打开,但是长时间中断之间的连接可能会中断。谢谢 @Tobia - 不要太担心开销,请检查我在这个答案中链接到的客户端套接字池库。始终推荐的做法是保持超时,并在该时间释放资源以有效地管理它们。记下我的话,它会让你的应用程序更好。祝你好运,:)【参考方案2】:

这也取决于打印机。它会打印它收到的每一个字符吗?当它收到一条完整的行时,它会累积行打印它们吗?还是等待完整的页面?还是为了完整的工作?在这种情况下,根据打印机协议,您可能必须关闭打印机的套接字才能意识到这是打印作业的结束。

另一方面:在许多企业环境中,防火墙会切断在某些(可配置的)时间段内不活动的套接字。在这种情况下,您最好在作业结束时关闭套接字。

最后,finalize 毫无用处。查一下。

【讨论】:

打印机等待其结束命令,在这种情况下是 ZPL 打印机,但我可以保持打开连接,打印不需要关闭连接。关于防火墙的很好的说明,事实并非如此,但我应该考虑一下。 您最好不要将应用程序编写为依赖于特定的打印机类型。这些事情发生了变化。

以上是关于我应该关闭tcp连接吗?的主要内容,如果未能解决你的问题,请参考以下文章

二十TCP三次连接四次关闭

如何模拟强制关闭的 TCP 连接?

socket 如果不关闭会自动关闭吗?为啥要心跳连接?

病毒扫描可以关闭 java TCP 套接字连接吗?

我需要心跳来保持 TCP 连接打开吗?

TCP连接创建和关闭事件挂钩[关闭]