Question

I am working on a Java application that is supposed to SCP to our remote computer a particular file. I am using the Jsch library, and have followed the ScpTo.java example from the website @ (http://www.jcraft.com/jsch/examples/ScpTo.java)

However, the scp command is being difficult within the application, so I attempted running the SCP command manually outside of the application in my terminal using Cygwin.

My command looked like this:

    scp -t /home/user/test.csv
    C0644 197171 C:\Users\user\Documents\test.csv

The output of the command reads:

C:\Users\user\Documents\test.csv                0%    0     0.0KB/s - stalled -

That's all it seems to do. Now I thought maybe this was a firewall problem, so I tried several other remote machines, and they still gave me the same problem.

Any ideas on how to handle this kind of problem?

Thank you so much,

Joe

EDIT: Here's the Java Code:

import java.awt.Container;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;

import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.UIKeyboardInteractive;
import com.jcraft.jsch.UserInfo;

class HPCConnector
{
    private static String username = "username";
    private static String host = "host.edu";

    JSch jsch;
    Session session;
    UserInfo ui;

    public HPCConnector() throws JSchException
    {
        jsch = new JSch();
        session = jsch.getSession(username, host, 22);
        ui = new HPCUserInfo();
        session.setUserInfo(ui);
    }

    public boolean validateConnection() 
    {
        boolean status = true;
        try {
            session.connect();
            if (status)
                return status;
            } catch (JSchException e) {
                e.printStackTrace();
                status = false;
            }
        return status;
    }

    public static class HPCUserInfo 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);
        }
        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;
        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
          }
        }
     }

    public void transferToHPC(File spreadsheet) throws JSchException
    {
        OutputStream out = null;
        InputStream in = null;
        String command = "scp -t /home/user/" + spreadsheet.getName();
        Channel channel = session.openChannel("exec");
        ((ChannelExec)channel).setCommand(command);
        try{
            out = channel.getOutputStream();
            in = channel.getInputStream();
        } catch (IOException ex) {
            ex.printStackTrace();
        }

        System.out.println(command);
        long fileSize=  spreadsheet.length();

        channel.connect();

        command = "C0644 " + fileSize + " " + spreadsheet.getAbsolutePath() + "\n";
        try {
            if(checkAck(in)!=0){
                System.exit(0);
              }
            out.write(command.getBytes());
            out.flush();

            FileInputStream fis = new FileInputStream(spreadsheet);
            byte[] buffer = new byte[1024];

            while (true)
            {
                int length = fis.read(buffer, 0, buffer.length);
                if (length <= 0)
                    break;
                out.write(buffer, 0, 1);
            }
            fis.close();
            fis = null;
            System.out.println(command);

            buffer[0] = 0;
            out.write(buffer, 0, 1);
            out.flush();

            out.close();
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        channel.disconnect();
        session.disconnect();
    }

      static int checkAck(InputStream in) throws IOException{
            int b=in.read();
            // b may be 0 for success,
            //          1 for error,
            //          2 for fatal error,
            //          -1
            if(b==0) return b;
            if(b==-1) return b;

            if(b==1 || b==2){
              StringBuffer sb=new StringBuffer();
              int c;
              do {
            c=in.read();
            sb.append((char)c);
              }
              while(c!='\n');
              if(b==1){ // error
            System.out.print(sb.toString());
              }
              if(b==2){ // fatal error
            System.out.print(sb.toString());
              }
            }
            return b;
          }
}

EDIT2: No exceptions are appearing on the console, and the main function that is giving me trouble is transferToHPC(File spreadsheet)

EDIT3: Well I finally did end up giving up on this; was able to use JSch's Sftp classes and it worked the way I intended.

I did more reading and read Kenster's answer, I think I'm to leave the -t flag for scp to handle internally :) Thanks guys!!

Était-ce utile?

La solution

Do I understand you correctly? You manually ran the scp -t command and typed in the C0644 line, and you got the stalling message from that? That doesn't indicate any kind of problem.

scp -t is normally the receiving end of an scp transfer. It's launched by another scp instance which is going to send files to the receiving end. The sending scp instance starts the receiver, sends the C line to mark that a file is coming, then sends the data for the file.

What you did is to manually and interactively start a receiver, and send to it a C line indicating that a file was coming. After that, the receiver was expecting to read the data for the file. Since you weren't sending any file data, the receiver eventually printed a status message indicating the transfer was stalled.

The only problem with that is that humans don't normally run scp -t directly. The scp program worked exactly the way you'd expect it to under these circumstances.

Autres conseils

This issue can happen when your file transfer process tries to take up large bandwidth but due to issue with network or firewall it is not able to get that bandwidth.

Try with l option : scp -l x "file" "destination" here x specifies kb/sec. So if you give 256 as value of x then bandwidth used would be 256kb/sec

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top