我应该关闭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连接吗?的主要内容,如果未能解决你的问题,请参考以下文章