代码拉取完成,页面将自动刷新
/**
* @Time: 2019/1/15 14:01
* @Author: wangmin
* @File: inner_to_outer_connection.go
* @Software: GoLand
*/
package connection
import (
"encoding/json"
"errors"
"io"
"log"
"net"
"strconv"
"sync"
"time"
"transponder/event"
)
// 内网到外网服务的连接
type InnerToOuterConnection struct {
Id uint64
Status int
StatusMonitor func(id uint64, status int)
OutServerAddress string
OutServerAuthKey string
outServerConn net.Conn
OutServerConnWriteLock sync.Mutex
ProxyAddress string
}
// 与外网服务器通讯
func (itoc *InnerToOuterConnection) communicate(single int) error {
if itoc.outServerConn == nil {
return errors.New("please register first")
}
var sb []byte
switch single {
case event.Ping:
//ping
sb = event.GenerateSignal(event.Ping, "")
case event.Auth:
//授权
sb = event.GenerateSignal(event.Auth, itoc.OutServerAuthKey)
case event.StartProxy:
//准备转发
sb = event.GenerateSignal(event.StartProxy, "")
default:
return errors.New("不支持的信号类型")
}
itoc.OutServerConnWriteLock.Lock()
_, err := itoc.outServerConn.Write(sb)
itoc.OutServerConnWriteLock.Unlock()
if err == nil {
return nil
}
itoc.Close()
return err
}
// 读取服务器数据
func (itoc *InnerToOuterConnection) Read() {
for {
if itoc.Status == StatusProxy || itoc.Status == StatusClose {
return
}
buf := make([]byte, event.PackageLength)
n, err := itoc.outServerConn.Read(buf)
if err != nil {
log.Println("read from server connection error:" + err.Error())
itoc.Close()
return
}
if n != event.PackageLength {
log.Println("read from server connection error data length error")
itoc.Close()
return
}
signal := &event.Signal{}
err = json.Unmarshal(buf, signal)
if err != nil {
log.Println("cant not parse outer server signal data:" + string(buf) + " error:" + err.Error())
itoc.Close()
return
}
switch signal.T {
case event.StartProxy:
itoc.Status = StatusProxy
itoc.Proxy()
return
default:
log.Println("unknown event:" + strconv.Itoa(signal.T))
itoc.Close()
return
}
}
}
// 连接外网服务器并注册
func (itoc *InnerToOuterConnection) Register() {
sc, err := net.Dial("tcp", itoc.OutServerAddress)
if err != nil {
log.Println("connect to server error:" + err.Error())
itoc.Close()
return
}
itoc.outServerConn = sc
err = itoc.communicate(event.Auth)
if err != nil {
//注册失败
log.Println("register fail:" + err.Error())
itoc.Close()
return
}
itoc.Status = StatusOk
itoc.StatusMonitor(itoc.Id, itoc.Status)
}
// 维持与服务器的连接
func (itoc *InnerToOuterConnection) Ping() {
if itoc.Status == StatusInit || itoc.Status == StatusProxy || itoc.outServerConn == nil {
return
}
err := itoc.communicate(event.Ping)
if err != nil {
log.Println("ping fail:" + err.Error())
return
}
}
// 开始数据转发
func (itoc *InnerToOuterConnection) Proxy() {
//log.Println("内部服务开始转发")
itoc.Status = StatusProxy
itoc.StatusMonitor(itoc.Id, itoc.Status)
//发送转发信号
err := itoc.communicate(event.StartProxy)
if err != nil {
log.Println("send proxy signal fail:" + err.Error())
return
}
//开始转发
_ = itoc.outServerConn.SetReadDeadline(time.Now().Add(time.Second * 90))
_ = itoc.outServerConn.SetWriteDeadline(time.Now().Add(time.Second * 90))
proxyConn, err := net.Dial("tcp", itoc.ProxyAddress)
if err != nil {
itoc.Close()
log.Println("connect to proxy server error:" + err.Error())
return
}
_ = proxyConn.SetReadDeadline(time.Now().Add(time.Second * 90))
_ = proxyConn.SetWriteDeadline(time.Now().Add(time.Second * 90))
go func() {
_, _ = io.Copy(itoc.outServerConn, proxyConn)
itoc.Close()
if proxyConn != nil {
_ = proxyConn.Close()
}
}()
go func() {
_, _ = io.Copy(proxyConn, itoc.outServerConn)
itoc.Close()
if proxyConn != nil {
_ = proxyConn.Close()
}
}()
}
// 关闭连接
func (itoc *InnerToOuterConnection) Close() {
itoc.Status = StatusClose
if itoc.outServerConn != nil {
_ = itoc.outServerConn.Close()
itoc.outServerConn = nil
}
itoc.StatusMonitor(itoc.Id, itoc.Status)
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。