You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
115 lines
2.3 KiB
115 lines
2.3 KiB
package telnet |
|
|
|
import ( |
|
"bytes" |
|
"fmt" |
|
"net" |
|
"strings" |
|
|
|
"github.com/gansidui/gotcp" |
|
) |
|
|
|
var ( |
|
endTag = []byte("\r\n") // Telnet command's end tag |
|
) |
|
|
|
// Packet |
|
type TelnetPacket struct { |
|
pType string |
|
pData []byte |
|
} |
|
|
|
func (p *TelnetPacket) Serialize() []byte { |
|
buf := p.pData |
|
buf = append(buf, endTag...) |
|
return buf |
|
} |
|
|
|
func (p *TelnetPacket) GetType() string { |
|
return p.pType |
|
} |
|
|
|
func (p *TelnetPacket) GetData() []byte { |
|
return p.pData |
|
} |
|
|
|
func NewTelnetPacket(pType string, pData []byte) *TelnetPacket { |
|
return &TelnetPacket{ |
|
pType: pType, |
|
pData: pData, |
|
} |
|
} |
|
|
|
type TelnetProtocol struct { |
|
} |
|
|
|
func (this *TelnetProtocol) ReadPacket(conn *net.TCPConn) (gotcp.Packet, error) { |
|
fullBuf := bytes.NewBuffer([]byte{}) |
|
for { |
|
data := make([]byte, 1024) |
|
|
|
readLengh, err := conn.Read(data) |
|
|
|
if err != nil { //EOF, or worse |
|
return nil, err |
|
} |
|
|
|
if readLengh == 0 { // Connection maybe closed by the client |
|
return nil, gotcp.ErrConnClosing |
|
} else { |
|
fullBuf.Write(data[:readLengh]) |
|
|
|
index := bytes.Index(fullBuf.Bytes(), endTag) |
|
if index > -1 { |
|
command := fullBuf.Next(index) |
|
fullBuf.Next(2) |
|
//fmt.Println(string(command)) |
|
|
|
commandList := strings.Split(string(command), " ") |
|
if len(commandList) > 1 { |
|
return NewTelnetPacket(commandList[0], []byte(commandList[1])), nil |
|
} else { |
|
if commandList[0] == "quit" { |
|
return NewTelnetPacket("quit", command), nil |
|
} else { |
|
return NewTelnetPacket("unknow", command), nil |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
|
|
type TelnetCallback struct { |
|
} |
|
|
|
func (this *TelnetCallback) OnConnect(c *gotcp.Conn) bool { |
|
addr := c.GetRawConn().RemoteAddr() |
|
c.PutExtraData(addr) |
|
fmt.Println("OnConnect:", addr) |
|
c.AsyncWritePacket(NewTelnetPacket("unknow", []byte("Welcome to this Telnet Server")), 0) |
|
return true |
|
} |
|
|
|
func (this *TelnetCallback) OnMessage(c *gotcp.Conn, p gotcp.Packet) bool { |
|
packet := p.(*TelnetPacket) |
|
command := packet.GetData() |
|
commandType := packet.GetType() |
|
|
|
switch commandType { |
|
case "echo": |
|
c.AsyncWritePacket(NewTelnetPacket("echo", command), 0) |
|
case "login": |
|
c.AsyncWritePacket(NewTelnetPacket("login", []byte(string(command)+" has login")), 0) |
|
case "quit": |
|
return false |
|
default: |
|
c.AsyncWritePacket(NewTelnetPacket("unknow", []byte("unknow command")), 0) |
|
} |
|
|
|
return true |
|
} |
|
|
|
func (this *TelnetCallback) OnClose(c *gotcp.Conn) { |
|
fmt.Println("OnClose:", c.GetExtraData()) |
|
}
|
|
|