Results 1 to 11 of 11
Thread: Creating an InputStream
- 07-16-2008, 04:51 PM #1
Member
- Join Date
- Jun 2008
- Posts
- 11
- Rep Power
- 0
Creating an InputStream
Hi,
What i'm doing is trying to send ssh commands using java to a server. I'm using the Jsch package to do this. The ssh part works, what i'm having trouble with is sending the commands to the server. There is an example which creates a shell in the console, it looks like this:
This works and connects to the server correctly (since you can see the logon being printed in the console), but it requires that the user enter commands from the console:Java Code:public class Shell { public static void main(String[] arg) { try { JSch jsch=new JSch(); String host = "host"; String user= "user"; Session session=jsch.getSession(user, host, 22); session.setPassword("pass"); session.setConfig("StrictHostKeyChecking", "no"); session.connect(30000); // making a connection with timeout. Channel channel=session.openChannel("shell"); channel.setInputStream(System.in); channel.setOutputStream(System.out); channel.connect(30000); } catch(Exception e) { System.out.println(e); } } }
channel.setInputStream(System.in);
What I want to do is make my own input stream and then send commands. I have been looking into the BufferedInputStream class, but I can't get it to work, and all the examples are for reading from files.
What I want to do is something like this:
String command = "ls -l";
and then somehow send command to an InputStream. That way I can replace System.in with my own InputStream.
Thanks.
- 07-16-2008, 05:00 PM #2
Not sure what this means. I read "send" as to write and InputStream as a way to read.send command to an InputStream
There is a System class method that allows you to replace System.in with your class. Read the API doc.
Perhaps the Process and Runtime classes would help.
- 07-16-2008, 05:08 PM #3
Member
- Join Date
- Jun 2008
- Posts
- 11
- Rep Power
- 0
Let me clarify:
Basically what I think I need to do is something like create an InputStream:
Then instead of having the line:Java Code:InputStream toServer;
I would have:Java Code:channel.setInputStream(System.in);
The problem is how can I write to the input stream 'toServer'?Java Code:channel.setInputStream(toServer);
- 07-16-2008, 05:34 PM #4
ByteChannel
Probably, you are not looking for Process (Java 2 Platform SE v1.4.2)
What is seems you want to do is represented by a somewhat misnamed ByteArrayOutputStream (Java 2 Platform SE v1.4.2) in which the read / write operations occur to memory.
To do this with Channels would either be ReadableByteChannel (Java 2 Platform SE v1.4.2) or WritableByteChannel (Java 2 Platform SE v1.4.2)Introduction to Programming Using Java.
Cybercartography: A new theoretical construct proposed by D.R. Fraser Taylor
- 07-16-2008, 05:50 PM #5
I think what you want to do is control what your InputStream reads. A way to do that is to create your own class that extends InputStream and pass that in the method setInputStream().
You'll "write to the input stream" by returning data as the input stream is read.
Or using Nicholas's idea, if you know exactly what you want to be read, create a ByteArrayInputStream with preloaded data and pass an instance of it to the set...() method.
- 07-16-2008, 08:59 PM #6
Member
- Join Date
- Jun 2008
- Posts
- 11
- Rep Power
- 0
Ok, first of all thanks Nicholas and Norm, the ByteArrayInputStream works well. So what I have is:
And that will send the command "ls -l" to the server and the result prints to the console.Java Code:ByteArrayInputStream bi = new ByteArrayInputStream("ls -l\n".getBytes()); channel.setInputStream(bi);
What I want to do now is send a second command to the server. In the original code (my first post), with System.in, you can type in as many commands as you want into the console one after another. So what I need is a way to change ByteArrayInputStream to be something else. I tried:
but it doesn't do anything. Any ideas?Java Code:bi = new ByteArrayInputStream("ls -l\n".getBytes());
My current code is:
Thanks.Java Code:import com.jcraft.jsch.*; import java.io.*; public class Shell { public static void main(String[] arg) { try { JSch jsch=new JSch(); String host = "host"; String user= "user"; Session session=jsch.getSession(user, host, 22); session.setPassword("pass"); session.setConfig("StrictHostKeyChecking", "no"); //session.connect(); session.connect(30000); // making a connection with timeout. Channel channel = session.openChannel("shell"); ByteArrayInputStream bi = new ByteArrayInputStream("ls -l\r".getBytes()); channel.setInputStream(bi); channel.setOutputStream(System.out); //channel.connect(); channel.connect(30000); } catch(Exception e) { System.out.println(e); } } }
- 07-16-2008, 10:16 PM #7
short of reading the entire code, what I was working on yesterday is close to this.
Still wrestling with some fundamental concepts but in general we have to get a byte array reference of some kind and do length and so on off of that.
IOW:
byte[] butylene = "someString or other string".getBytes();
then construct byte array output stream using default constructor.
Then and only then do what you are trying to do using the methods as documented in class java.io.ByteArrayOutputStream;//
As Norm observes, you are trying to get control on Stream such and such so as to control the feed to some sink...
That is done with a while byte array still has bytes do so and so. If I may suggest: Study the methods of DataOutputStream.
Observe the limitations of strong typing. Weep and read.Introduction to Programming Using Java.
Cybercartography: A new theoretical construct proposed by D.R. Fraser Taylor
- 07-16-2008, 11:08 PM #8
andByteArrayInputStream works well.
The code looks the same for when it works and when it doesn't do anything. Could you explain some more?it doesn't do anything
Can all the commands be together or do you need to a separate connect for each one?I want to do now is send a second command
- 07-17-2008, 12:40 AM #9
no constructor taking byte[]
Neither of these constructors are as poster has.Java Code://Creates a new byte array output stream. ByteArrayOutputStream() // Creates a new byte array output stream, with a buffer capacity of the specified size, in bytes. ByteArrayOutputStream(int size)
ByteArrayOutputStream (Java 2 Platform SE 5.0)Introduction to Programming Using Java.
Cybercartography: A new theoretical construct proposed by D.R. Fraser Taylor
- 07-17-2008, 03:24 AM #10
I guess you need new glasses. The OP posted constructors for ...In... not ...Out...
- 07-12-2011, 04:48 AM #11
Member
- Join Date
- Jul 2011
- Posts
- 1
- Rep Power
- 0
You need to think Terminal Emulation instead
Norm,
I also had your problem. Its an old post but I couldn't find an answer anywhere else so I uploaded my solution.
Firstly, the main problem is that JSch takes (rapid) asynchronious reads from what it expects to be a console or silimar until there is no text left to send and it breaks the conection. As suggested above you can override InputStream (or BufferedInputStream) and the Session Class will call getBytes() from the IO class with the set InputStream in a loop until no bytes are left and it breaks so even if you create your own inputStream it is still a one shot deal. Once the buffer is empty the connection is over. In my example I wanted to send a polling command every 10 seconds and monitor a result and this couldn't be achieved.
By the very fact that JSch 'WRITES' to an InputStream and "READS" from a OutputStream it is clear that our perspective is backwards to the initial intent of the application. Instead of a Shell you need to look at jcterm which is a Terminal emulator that allows Synch 'Triggered' writes to a server and polled reads.
The package com.jcraft.jcterm has a Class called JSchSession which is a wrapper for the Session Class (Not extended but exposes the Session through an accessor).This Class allows you to open a channel and get InputStreams and OutputStreams to the server in a way that you are expecting. From there you can run a Thread to accept the inputs and write (and Flush) to the outputStream.
E.G:
package SSHTests;
import com.jcraft.jcterm.JSchSession;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.UIKeyboardInteractive;
import com.jcraft.jsch.UserInfo;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
/**
*
* @author dcolcott
*/
public class TestSHH_WithConnection{
public static void main(String args[]){
TestSHH_WithConnection app = new TestSHH_WithConnection();
app.initSession();
app.startreadThread();
app.shInputDialog();
}
private void initSession(){
try{
UserInfo ui=new MyUserInfo();
jschsession=JSchSession.getSession("user", "pass", "host", 22, ui, null);
java.util.Properties config=new java.util.Properties();
config.put("compression.s2c", "none");
config.put("compression.c2s", "none");
config.put("compression.s2c", "zlib,none");
config.put("compression.c2s", "zlib,none");
jschsession.getSession().setConfig(config);
jschsession.getSession().rekey();
Channel channel=null;
channel=jschsession.getSession().openChannel("shel l");
fout=channel.getOutputStream();
fin=channel.getInputStream();
channel.connect();
}catch(Exception e){e.printStackTrace();}
}
private void startreadThread(){new readInput().start();}
private void shInputDialog(){
JDialog d = new JDialog();
JPanel p = new JPanel();
final JTextField t = new JTextField();
t.setPreferredSize(new Dimension(250, 20));
JButton b = new JButton("Write");
b.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
try{
fout.write(t.getText().getBytes());
fout.write(KeyEvent.VK_ENTER);
fout.flush();
t.setText("");
}catch(Exception ex){ex.printStackTrace();}
}
});
p.add(t); p.add(b);
d.add(p); d.pack();
d.setVisible(true);
}
class readInput extends Thread{
@Override
public void run(){
int b;
try{
while(true){
b=fin.read();
if(b!=-1){
System.out.print((char)(b));
}else{
try{Thread.sleep(1000);}catch(InterruptedException intEx){}
}
}
}catch(IOException ex){
System.out.println("Reading from session caused an IOException. Out of read loop");
}
}
}
public static class MyUserInfo implements UserInfo, UIKeyboardInteractive{
public String getPassword(){ return passwd; }
public boolean promptYesNo(String str){
Object[] options={ "yes", "no" };
int foo=JOptionPane.showOptionDialog(null,
str,
"Warning",
JOptionPane.DEFAULT_OPTION,
JOptionPane.WARNING_MESSAGE,
null, options, options[0]);
return foo==0;
}
String passwd;
JTextField passwordField=(JTextField)new JPasswordField(20);
public String getPassphrase(){ return null; }
public boolean promptPassphrase(String message){ return true; }
public boolean promptPassword(String message){
Object[] ob={passwordField};
int result=JOptionPane.showConfirmDialog(null, ob, message,
JOptionPane.OK_CANCEL_OPTION);
if(result==JOptionPane.OK_OPTION){
passwd=passwordField.getText();
return true;
}
else{
return false;
}
}
public void showMessage(String message){
JOptionPane.showMessageDialog(null, message);
}
public String[] promptKeyboardInteractive(String destination,
String name, String instruction,
String[] prompt, boolean[] echo){
panel = new JPanel();
panel.setLayout(new GridBagLayout());
gbc.weightx = 1.0;
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.gridx = 0;
panel.add(new JLabel(instruction), gbc);
gbc.gridy++;
gbc.gridwidth = GridBagConstraints.RELATIVE;
JTextField[] texts=new JTextField[prompt.length];
for(int i=0; i<prompt.length; i++){
gbc.fill = GridBagConstraints.NONE;
gbc.gridx = 0;
gbc.weightx = 1;
panel.add(new JLabel(prompt[i]),gbc);
gbc.gridx = 1;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weighty = 1;
if(echo[i]){
texts[i]=new JTextField(20);
}
else{
texts[i]=new JPasswordField(20);
}
panel.add(texts[i], gbc);
gbc.gridy++;
}
if(JOptionPane.showConfirmDialog(null, panel,
destination+": "+name,
JOptionPane.OK_CANCEL_OPTION,
JOptionPane.QUESTION_MESSAGE)
==JOptionPane.OK_OPTION){
String[] response=new String[prompt.length];
for(int i=0; i<prompt.length; i++){
response[i]=texts[i].getText();
}
return response;
}
else{
return null; // cancel
}
}
final GridBagConstraints gbc = new GridBagConstraints(0,0,1,1,1,1,
GridBagConstraints.NORTHWEST,
GridBagConstraints.NONE,
new Insets(0,0,0,0),0,0);
private Container panel;
}
private JSchSession jschsession=null;
private OutputStream fout;
private InputStream fin;
}
Similar Threads
-
Converting InputStream to OutputStream
By Java Tip in forum Java TipReplies: 1Last Post: 01-11-2008, 10:13 PM -
Reading form inputStream and storing in ByteArray
By Java Tip in forum Java TipReplies: 0Last Post: 11-27-2007, 10:23 AM -
Reading bytes from InputStream
By Java Tip in forum Java TipReplies: 0Last Post: 11-25-2007, 07:51 PM -
Un expected behaviour when reading from inputstream
By adoorsarath in forum Advanced JavaReplies: 3Last Post: 08-10-2007, 05:02 PM


LinkBack URL
About LinkBacks
Reply With Quote

Bookmarks