Search code examples
javaperformancesocketsnetwork-programmingtcpclient

Should I close the tcp connection?


I have a Java printing application, it prints ticket to a network printer using raw TCP sockets. This application is a REST listener, when it receive a command, it prints using one single connection to a single ethernet thermal printer.

This is my code used by a singleton service:

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) try{wrapper.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) {}
    }

}

My question is: should it close its socket at the end of each print job? Or can a TCP socket stay opened for many hours waiting for jobs?

I don't know REST requests frequency, but I'm sure they can wait many hours but the also be called many in a minute. This is why I cannot answer, can a socket stay opened waiting for so long? In other hand can I open/close/open/close many sockets in few minutes? Should I complicate with a disconnection timer?


Solution

  • You're not using raw Sockets (it is not possible using existing Java's network standard package; you'll need to use native calls with the help of JNI for utilising raw Sockets).

    What you're using in your code seems to be a PrintServer having TCPSocket extending from the Java's Standard Package's TCP Socket. And, there's too much of code which has not been shared.

    My question is: should it close its socket at the end of each print job? Or can a TCP socket stay opened for many hours waiting for jobs?

    Ideally, each application should have process timeout, or release the resource after a certain period of time. It is the general principle of security (and best practices) to close sessions in case of request-waiting situations. By process, I mean the underlying resource if not being used should close the connection or/and give a timeout (depending on the application's use-case).

    So, yes, if the class TcpWrapper extends the class Socket, you should set the connect timeout as well as the read timeout. The most important thing is: "Once the operation is done, you should close the Socket at both the client and the Server end".

    You can utilise Socket pools to manage multiple connections for your print application as mentioned in the post Manage Client Socket Pool.