Search code examples
javasocketsiojschoutputstream

When I use JSch, can I use custom OutputStream with the socket?


When I use JSch lib, can I use custom OutputStream?

I want to wrap JSch message with Google Proto. So I have to use custom OutputStream.

I knew that JSch could set custom SocketFactory. So I made a custom SocketFactory.

But when session is connected, it was frozen. It didn't work.

I think that my custom OutputStream interrupted communication with SSH protocol.

Session session = jSch.getSession( "root", "localhost", 55000 );
session.setPassword( "root" );
session.setConfig( "StrictHostKeyChecking","no" );
session.setSocketFactory( new SocketFactory() {
    @Override
    public Socket createSocket( String host, int port ) throws IOException, UnknownHostException {

        return new Socket( host, port );
    }

    @Override
    public InputStream getInputStream( Socket socket ) throws IOException {

        return socket.getInputStream();
    }

    @Override
    public OutputStream getOutputStream( Socket socket ) throws IOException {

        return new CustomOutputStream();
    }
} );
session.connect();

And here is my custom stream.

public class CustomOutputStream extends OutputStream {

    @Override
    public void write( int b ) throws IOException {
        byte[] a = new byte[] { (byte) b };
        write(a, 0, 1);
    }

    @Override
    public void write( byte[] b, int off, int len ) throws IOException {
        System.out.println( b.hashCode() );

        // Todo
        //  JschProto.JschContents jschContents = // JschProto.JschContents.newBuilder().setContent( ByteString.copyFrom( b ) )
        //              .setType( "t" )
        //              .build();

        super.write(b, off, len);
    }
}

Solution

  • Your CustomOutputStream doesn't use the socket. Here's an example of how you could incorporate it into your design.

    public class CustomOutputStream extends OutputStream {
        private OutputStream innerStream;
    
        public CustomOutputStream(Socket socket) {
          this(socket.getOutputStream);
        }
    
        public CustomOutputStream(OutputStream delegate) {
          this.innerStream = delegate;
        }
    
        //TODO: Override more methods to delegate to innerStream
    
        @Override
        public void write( int b ) throws IOException {
            byte[] a = new byte[] { (byte) b };
            write(a, 0, 1);
        }
    
    
        @Override
        public void write( byte[] b, int off, int len ) throws IOException {
    
    
            System.out.println( b.hashCode() );
    
    // Todo
        //  JschProto.JschContents jschContents = // JschProto.JschContents.newBuilder().setContent( ByteString.copyFrom( b ) )
    //              .setType( "t" )
    //              .build();
    
            innerStream.write(b, off, len);
        }
    }