栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 系统运维 > 运维 > Linux

go实现ssh远程机器并传输文件

Linux 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

go实现ssh远程机器并传输文件

 项目目录结构:

 sshtool.go:

package ssh_tool

import (
	"flag"
	"fmt"
	"github.com/pkg/sftp"
	"golang.org/x/crypto/ssh"
	"io"
	"log"
	"net"
	"os"
	"path"
	"time"
)

// SshClient ssh客户端对象 /*
type SshClient struct {
	username string
	password string
	host string
	Client * ssh.Client
}

func (sshClient * SshClient) NewSshClient() *ssh.Client{
	flag.StringVar(&sshClient.username,"username","root","通过ssh2登录linux的用户名")
	flag.StringVar(&sshClient.password,"password","root","通过ssh2登录linux的密码")
	flag.StringVar(&sshClient.host,"host","192.168.56.25","通过ssh2登录linux的ip地址")
	flag.Parse()

	log.Println(sshClient.password)

	auth := make([]ssh.AuthMethod, 0)
	auth = append(auth, ssh.Password(sshClient.password))

	clientConfig := &ssh.ClientConfig{
		User:    sshClient.username,
		Auth:    auth,
		Timeout: 30 * time.Second,
		HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error {
			return nil
		},
	}

	addr := sshClient.host + ":22"
	client, err := ssh.Dial("tcp", addr, clientConfig) //连接ssh
	if err != nil {
		log.Fatal("连接ssh失败", err)
	}

	sshClient.Client = client
	return client
}

func (sshClient * SshClient) RunCmd(cmd string) string {
	session, err := sshClient.Client.NewSession()
	if err != nil{
		panic(err)
	}
	defer session.Close()

	runResult,err := session.CombinedOutput(cmd)
	if err != nil{
		panic(err)
	}
	return string(runResult)
}


func (sshClient * SshClient) UploadFile(localPath string, remoteDir string, remoteFileName string){
	ftpClient, err := sftp.NewClient(sshClient.Client)
	if err != nil {
		fmt.Println("创建ftp客户端失败", err)
		panic(err)
	}

	defer ftpClient.Close()

	fmt.Println(localPath, remoteFileName)
	srcFile, err := os.Open(localPath)
	if err != nil {
		fmt.Println("打开文件失败", err)
		panic(err)
	}
	defer srcFile.Close()

	dstFile, e := ftpClient.Create(path.Join(remoteDir, remoteFileName))
	if e != nil {
		fmt.Println("创建文件失败", e)
		panic(e)
	}
	defer dstFile.Close()

	buffer := make([]byte, 1024000)
	for {
		n, err := srcFile.Read(buffer)
		dstFile.Write(buffer[:n])
		//注意,由于文件大小不定,不可直接使用buffer,否则会在文件末尾重复写入,以填充1024的整数倍
		if err != nil {
			if err == io.EOF {
				fmt.Println("已读取到文件末尾")
				break
			} else {
				fmt.Println("读取文件出错", err)
				panic(err)
			}
		}
	}
}

func (sshClient * SshClient) DownloadFile(remotePath string, localDir string , localFilename string)  {
	ftpClient, err := sftp.NewClient(sshClient.Client)
	if err != nil {
		fmt.Println("创建ftp客户端失败", err)
		panic(err)
	}

	defer ftpClient.Close()

	srcFile, err := ftpClient.Open(remotePath)
	if err != nil {
		fmt.Println("文件读取失败", err)
		panic(err)
	}
	defer srcFile.Close()

	dstFile, e := os.Create(path.Join(localDir, localFilename))
	if e != nil {
		fmt.Println("文件创建失败", e)
		panic(e)
	}
	defer dstFile.Close()
	if _, err1 := srcFile.WriteTo(dstFile); err1 != nil {
		fmt.Println("文件写入失败", err1)
		panic(err1)
	}
	fmt.Println("文件下载成功")
}

const_values.go: 

package constkv

const (
	MSG_CODE_KEY = "code"
	MSG_CONTENT_KEY = "msg"
)

SSHRemote.go: 

package main

import (
	"SSH/constkv"
	"SSH/ssh_tool"
	"bufio"
	"encoding/json"
	"io"
	"log"
	"net/http"
)

var (
	sshClient = new(ssh_tool.SshClient)
	buffer = make([]byte,10240)
)

func handlerCmd(writer http.ResponseWriter, request *http.Request) {
	var resultMap = make(map[string]interface{})
	//处理错误的panic
	defer func() {
		err := recover()
		if err != nil{
			resultMap[constkv.MSG_CODE_KEY] = http.StatusOK
			resultMap[constkv.MSG_CONTENT_KEY] = err.(error).Error()
			bytes, _ := json.Marshal(&resultMap)
			writer.Write(bytes)
		}
	}()

	var bufferSlice = make([]byte,0)

	reader := request.Body
	bufferReader := bufio.NewReader(reader)

	for {
		length, err := bufferReader.Read(buffer)
		bufferSlice = append(bufferSlice,buffer[:length]...)
		if err == io.EOF{
			break
		}
	}

	log.Println(string(bufferSlice))
	var paramMap = make(map[string]interface{})
	_ = json.Unmarshal(bufferSlice, ¶mMap)

	log.Println(paramMap["cmd"])
	cmd := paramMap["cmd"]
	log.Println(cmd.(string) + "--------------------")

	if sshClient.Client != nil{
		runCmd := sshClient.RunCmd(cmd.(string))
		resultMap[constkv.MSG_CODE_KEY] = http.StatusOK
		resultMap[constkv.MSG_CONTENT_KEY] = runCmd
	}

	bytes, _ := json.Marshal(&resultMap)
	_ , _ = writer.Write(bytes)
}

func handleUploadFile(writer http.ResponseWriter, request *http.Request)  {
	var resultMap = make(map[string]interface{})
	//处理错误的panic
	defer func() {
		err := recover()
		if err != nil{
			resultMap[constkv.MSG_CODE_KEY] = http.StatusOK
			resultMap[constkv.MSG_CONTENT_KEY] = err.(error).Error()
			bytes, _ := json.Marshal(&resultMap)
			writer.Write(bytes)
		}

	}()
	var bufferSlice = make([]byte,0)
	reader := request.Body
	bufferReader := bufio.NewReader(reader)

	for {
		length, err := bufferReader.Read(buffer)
		bufferSlice = append(bufferSlice,buffer[:length]...)
		if err == io.EOF{
			break
		}
	}

	log.Println(string(bufferSlice))
	var paramMap = make(map[string]interface{})
	_ = json.Unmarshal(bufferSlice, ¶mMap)

	localPath := paramMap["localPath"]
	remoteDir := paramMap["remoteDir"]
	remoteFileName := paramMap["remoteFileName"]

	log.Println(localPath)
	log.Println(remoteDir)

	sshClient.UploadFile(localPath.(string),remoteDir.(string),remoteFileName.(string))
}

func handleDownloadFile(writer http.ResponseWriter, request *http.Request)  {
	var resultMap = make(map[string]interface{})
	//处理错误的panic
	defer func() {
		err := recover()
		if err != nil{
			resultMap[constkv.MSG_CODE_KEY] = http.StatusOK
			resultMap[constkv.MSG_CONTENT_KEY] = err.(error).Error()
			bytes, _ := json.Marshal(&resultMap)
			writer.Write(bytes)
		}

	}()
	var bufferSlice = make([]byte,0)
	reader := request.Body
	bufferReader := bufio.NewReader(reader)

	for {
		length, err := bufferReader.Read(buffer)
		bufferSlice = append(bufferSlice,buffer[:length]...)
		if err == io.EOF{
			break
		}
	}

	log.Println(string(bufferSlice))
	var paramMap = make(map[string]interface{})
	_ = json.Unmarshal(bufferSlice, ¶mMap)

	remotePath := paramMap["remotePath"]
	localDir := paramMap["localDir"]
	localFileName := paramMap["localFileName"]

	log.Println(remotePath)
	log.Println(localDir)
	log.Println(localFileName)

	sshClient.DownloadFile(remotePath.(string),localDir.(string),localFileName.(string))
}

func main(){
	//初始化ssh客户端
	sshClient.NewSshClient()
	//1.注册一个给定模式的处理器函数到DefaultServeMux
	http.HandleFunc("/", handlerCmd)
	http.HandleFunc("/uploadFile", handleUploadFile)
	http.HandleFunc("/downloadFile", handleDownloadFile)

	//2.设置监听的TCP地址并启动服务
	//参数1:TCP地址(IP+Port)
	//参数2:当设置为nil时表示使用DefaultServeMux
	err := http.ListenAndServe(":8080", nil)
	log.Fatal(err)
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/450318.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号