march1993
2021-02-24 14:08:38 +08:00
goang 自己写一个?
```golang
package main
import (
"fmt"
"net"
"os"
"io"
"time"
"os/signal"
"syscall"
)
type Config struct {
ListenAddr string
ForwardAddr string
}
var configs []*Config = []*Config{
// {ListenAddr: ":1995", ForwardAddr: "1.2.3.4:199"},
// {ListenAddr: ":8081", ForwardAddr: "5.6.7.8:8081"},
// {ListenAddr: ":2222", ForwardAddr: "9.10.11.12:22"},
{ListenAddr: ":8081", ForwardAddr: "192.168.1.10:30000"},
}
func worker(c *Config) {
fmt.Println("forwarding", c.ListenAddr, " to", c.ForwardAddr)
if l, err := net.Listen("tcp", c.ListenAddr); nil != err {
panic(err)
} else {
defer l.Close()
for {
if left, err := l.Accept(); nil != err {
fmt.Println("listen: accept error: ", err.Error())
continue
} else {
if right, err := net.Dial("tcp", c.ForwardAddr); nil != err {
fmt.Println("listen: dial error:", err.Error())
left.Close()
} else {
go Relay(left, right)
}
}
}
}
}
func main() {
c := make(chan os.Signal)
signal.Notify(c, os.Interrupt, syscall.SIGTERM)
for _, config := range configs {
go worker(config)
}
_ = <-c
}
func Relay(left, right net.Conn) (int64, int64, error) {
type res struct {
N int64
Err error
}
ch := make(chan res)
go func() {
n, err := io.Copy(right, left)
right.SetDeadline(time.Now()) // wake up the other goroutine blocking on right
left.SetDeadline(time.Now()) // wake up the other goroutine blocking on left
ch <- res{n, err}
}()
n, err := io.Copy(left, right)
right.SetDeadline(time.Now()) // wake up the other goroutine blocking on right
left.SetDeadline(time.Now()) // wake up the other goroutine blocking on left
rs := <-ch
if err == nil {
err = rs.Err
}
return n, rs.N, err
}
```