宝塔用Go实现内网穿透
1.安装Go语言环境
2.目录结构
/www/wwwroot/根目录/
├── constant/
│ └── constant.go
├── helper/
│ └── helper.go
├── go.mod
└── main.go
PS: go.mod
是生成的
在根目录
执行命令:go mod init 根目录
生成go.mod
手动按照目录创建go文件。
main.go代码(自己替换根目录
):
package main
import (
"io"
"log"
"net"
"根目录/constant"
"根目录/helper"
)
var serverConn *net.TCPConn
var appConn *net.TCPConn
func main() {
go serverListen()
go appListen()
go tunnelListen()
select {}
}
func serverListen() {
tcpListener, err := helper.CreateListen("0.0.0.0" + constant.ServerPort)
if err != nil {
panic(err)
}
log.Printf("服务端监听地址为:%s\n", tcpListener.Addr().String())
for {
serverConn, err = tcpListener.AcceptTCP()
if err != nil {
log.Printf("接收连接失败,错误信息为:%s\n", err.Error())
return
}
go helper.KeepAlive(serverConn)
}
}
func tunnelListen() {
tcpListener, err := helper.CreateListen("0.0.0.0" + constant.TunnelPort)
if err != nil {
panic(err)
}
log.Printf("隧道监听地址为:%s\n", tcpListener.Addr().String())
for {
tunnelConn, err := tcpListener.AcceptTCP()
if err != nil {
log.Printf("接收连接失败,错误信息为:%s\n", err.Error())
return
}
go io.Copy(appConn, tunnelConn)
go io.Copy(tunnelConn, appConn)
}
}
func appListen() {
tcpListener, err := helper.CreateListen(constant.AppTargetPort)
if err != nil {
panic(err)
}
log.Printf("应用目的服务端监端口地址为:%s\n", tcpListener.Addr().String())
for {
appConn, err = tcpListener.AcceptTCP()
if err != nil {
log.Printf("接收连接失败,错误信息为:%s\n", err.Error())
return
}
_, err = serverConn.Write([]byte("New Connection"))
if err != nil {
log.Printf("发送消息失败,错误信息为:%s\n", err.Error())
}
}
}
helper/helper.go代码:
package helper
import (
"log"
"net"
"time"
)
func CreateListen(listenAddr string) (*net.TCPListener, error) {
tcpAddr, err := net.ResolveTCPAddr("tcp", listenAddr)
if err != nil {
return nil, err
}
tcpListener, err := net.ListenTCP("tcp", tcpAddr)
return tcpListener, err
}
func CreateConnect(connectAddr string) (*net.TCPConn, error) {
tcpAddr, err := net.ResolveTCPAddr("tcp", connectAddr)
if err != nil {
return nil, err
}
tcpConn, err := net.DialTCP("tcp", nil, tcpAddr)
return tcpConn, err
}
func KeepAlive(conn *net.TCPConn) {
for {
_, err := conn.Write([]byte("KeepAlive"))
if err != nil {
log.Printf("[KeepAlive] Error %s", err)
return
}
time.Sleep(time.Second * 30)
}
}
func GetDataFromConnection(bufSize int, conn *net.TCPConn) ([]byte, error) {
b := make([]byte, 0)
for {
data := make([]byte, bufSize)
n, err := conn.Read(data)
if err != nil {
return nil, err
}
b = append(b, data[:n]...)
if n < bufSize {
break
}
}
return b, nil
}
constant/constant.go代码:
package constant
const (
AppPort = ":8080" //本地端口
ServerPort = ":8081"
TunnelPort = ":8082"
AppTargetPort = ":8083"
ServerIP = "YOUR_SERVER_IP"
ServerAddr = ServerIP + ServerPort
TunnelAddr = ServerIP + TunnelPort
BufSize = 1024
)
执行编译代码命令:`go build -o server
`
会生成一个server文件,然后执行它即可
客户端一样
独特见解