golang实现telnet

网上搜了两篇golang实现telnet的,功能可以但不能持续输入,稍加修改.

代码

最终代码如下:

package main

import (
	"fmt"
	"log"
	"net"
	"strings"
	"time"
	"bufio"
	"os"
	"io"
)

type TelnetClient struct {
	IP               string
	Port             string
	IsAuthentication bool
	UserName         string
	Password         string
}

const (
	//经过测试,linux下,延时需要大于100ms
	TIME_DELAY_AFTER_WRITE = 500 //500ms
)
var g_WriteChan chan string

func main() {
	g_WriteChan = make(chan string)
	telnetClientObj := new(TelnetClient)
	telnetClientObj.IP = "192.168.1.104"
	telnetClientObj.Port = "23"
	telnetClientObj.IsAuthentication = false
	//telnetClientObj.UserName = "userOne"
	//telnetClientObj.Password = "123456"
	//fmt.Println(telnetClientObj.PortIsOpen(5))
	go telnetClientObj.Telnet( 20)

	for {
		line := readLine()
		g_WriteChan <- string(line)
	}
}

func readLine() string {
	//fmt.Print("> ")
	line, err := bufio.NewReader(os.Stdin).ReadString('\n')
	if err != nil && err != io.EOF {
		log.Fatal(err)
	}
	return strings.TrimSpace(line)
}

func (this *TelnetClient) PortIsOpen(timeout int) bool {
	raddr := this.IP + ":" + this.Port
	conn, err := net.DialTimeout("tcp", raddr, time.Duration(timeout)*time.Second)
	if nil != err {
		log.Println("pkg: model, func: PortIsOpen, method: net.DialTimeout, errInfo:", err)
		return false
	}
	defer conn.Close()
	return true
}

func (this *TelnetClient) Telnet( timeout int) (err error) {
	raddr := this.IP + ":" + this.Port
	conn, err := net.DialTimeout("tcp", raddr, time.Duration(timeout)*time.Second)
	if nil != err {
		log.Println("pkg: model, func: Telnet, method: net.DialTimeout, errInfo:", err)
		return
	}
	defer conn.Close()
	if false == this.telnetProtocolHandshake(conn) {
		log.Println("pkg: model, func: Telnet, method: this.telnetProtocolHandshake, errInfo: telnet protocol handshake failed!!!")
		return
	}
	go func() {
		for {
			data := make([]byte, 1024)
			_, err := conn.Read(data)
			if err != nil {
				fmt.Println(err)
				break
			}
			//strData := string(data)
			fmt.Printf("%s", data)
		}
	} ()

	//	conn.SetReadDeadline(time.Now().Add(time.Second * 30))
	for {
		select {
			case  cmd, _:= <- g_WriteChan:
				_, err = conn.Write([]byte(cmd + "\n"))
				if nil != err {
					log.Println("pkg: model, func: Telnet, method: conn.Write, errInfo:", err)
					return
				}
				break
			default :
				time.Sleep( 100 * time.Millisecond)
			    continue
		}
	}
	fmt.Println("Out telnet!!!!!!")
	return 
}

func (this *TelnetClient) telnetProtocolHandshake(conn net.Conn) bool {
	var buf [4096]byte
	n, err := conn.Read(buf[0:])
	if nil != err {
		log.Println("pkg: model, func: telnetProtocolHandshake, method: conn.Read, errInfo:", err)
		return false
	}
	//fmt.Println(string(buf[0:n]))
	//fmt.Println((buf[0:n]))

	buf[1] = 252
	buf[4] = 252
	buf[7] = 252
	buf[10] = 252
	//fmt.Println((buf[0:n]))
	n, err = conn.Write(buf[0:n])
	if nil != err {
		log.Println("pkg: model, func: telnetProtocolHandshake, method: conn.Write, errInfo:", err)
		return false
	}

	n, err = conn.Read(buf[0:])
	if nil != err {
		log.Println("pkg: model, func: telnetProtocolHandshake, method: conn.Read, errInfo:", err)
		return false
	}
	//fmt.Println(string(buf[0:n]))
	//fmt.Println((buf[0:n]))

	buf[1] = 252
	buf[4] = 251
	buf[7] = 252
	buf[10] = 254
	buf[13] = 252
	fmt.Println((buf[0:n]))
	n, err = conn.Write(buf[0:n])
	if nil != err {
		log.Println("pkg: model, func: telnetProtocolHandshake, method: conn.Write, errInfo:", err)
		return false
	}

	n, err = conn.Read(buf[0:])
	if nil != err {
		log.Println("pkg: model, func: telnetProtocolHandshake, method: conn.Read, errInfo:", err)
		return false
	}
	//fmt.Println(string(buf[0:n]))
	//fmt.Println((buf[0:n]))

	buf[1] = 252
	buf[4] = 252
	//fmt.Println((buf[0:n]))
	n, err = conn.Write(buf[0:n])
	if nil != err {
		log.Println("pkg: model, func: telnetProtocolHandshake, method: conn.Write, errInfo:", err)
		return false
	}

	n, err = conn.Read(buf[0:])
	if nil != err {
		log.Println("pkg: model, func: telnetProtocolHandshake, method: conn.Read, errInfo:", err)
		return false
	}
	//fmt.Println(string(buf[0:n]))
	//fmt.Println((buf[0:n]))

	if false == this.IsAuthentication {
		return true
	}

	n, err = conn.Write([]byte(this.UserName + "\n"))
	if nil != err {
		log.Println("pkg: model, func: telnetProtocolHandshake, method: conn.Write, errInfo:", err)
		return false
	}
	time.Sleep(time.Millisecond * TIME_DELAY_AFTER_WRITE)

	n, err = conn.Read(buf[0:])
	if nil != err {
		log.Println("pkg: model, func: telnetProtocolHandshake, method: conn.Read, errInfo:", err)
		return false
	}
	//fmt.Println(string(buf[0:n]))

	n, err = conn.Write([]byte(this.Password + "\n"))
	if nil != err {
		log.Println("pkg: model, func: telnetProtocolHandshake, method: conn.Write, errInfo:", err)
		return false
	}
	time.Sleep(time.Millisecond * TIME_DELAY_AFTER_WRITE)

	n, err = conn.Read(buf[0:])
	if nil != err {
		log.Println("pkg: model, func: telnetProtocolHandshake, method: conn.Read, errInfo:", err)
		return false
	}
	//fmt.Println(string(buf[0:n]))
	return true
}

结果

[13 252 10]
XXX:/ # 
XXX:/ # ls
ls    
charger           init.hidolphin.rc    property_contexts sys                    
d                 init.usb.configfs.rc root              tmp                
data              init.usb.rc          sbin              ueventd.bigfish.rc 
default.prop      init.zygote32.rc     sdcard            ueventd.rc         
dev               initrc               seapp_contexts    vendor             
etc               mnt                  securestore       
file_contexts.bin nativedata           selinux_version   
XXX:/ # cd /tmp
cd /tmp
XXX:/tmp # ls
ls
XXX:/tmp # cd /ar
cd /ar
/system/bin/sh: cd: /ar: No such file or directory

参考文章:

(推荐)https://blog.csdn.net/wangkai_123456/article/details/70167943
(推荐)https://blog.csdn.net/banfushen007/article/details/119033203
https://blog.csdn.net/qq_37102984/article/details/123009654
https://blog.csdn.net/qq_38626043/article/details/104360182
https://cloud.tencent.com/developer/article/1456243

posted on 2022-09-22 13:58  步孤天  阅读(1539)  评论(0编辑  收藏  举报