zoukankan      html  css  js  c++  java
  • Go实现tcp代理

    nginx默认只能代理http,而且只能监听80端口,这个就不能忍了,自己撸一个

    package main
    
    import (
        "flag"
        "fmt"
        "io"
        "net"
        "os"
        "strings"
        "sync"
    )
    
    var lock sync.Mutex
    var trueList []string
    var ip string
    var list string
    
    func main() {
        flag.StringVar(&ip, "l", ":9897", "-l=0.0.0.0:9897 指定服务监听的端口")
        flag.StringVar(&list, "d", "127.0.0.1:1789,127.0.0.1:1788", "-d=127.0.0.1:1789,127.0.0.1:1788 指定后端的IP和端口,多个用','隔开")
        flag.Parse()
        trueList = strings.Split(list, ",")
        if len(trueList) <= 0 {
            fmt.Println("-l=0.0.0.0:9897 -d=127.0.0.1:1789")
            os.Exit(1)
        }
        server()
    }
    
    func server() {
        lis, err := net.Listen("tcp", ip)
        if err != nil {
            fmt.Println(err)
            return
        }
        defer lis.Close()
        for {
            conn, err := lis.Accept()
            if err != nil {
                fmt.Println("建立连接错误:%v
    ", err)
                continue
            }
            fmt.Println(conn.RemoteAddr(), conn.LocalAddr())
            go handle(conn)
        }
    }
    
    func handle(sconn net.Conn) {
        defer sconn.Close()
        ip, ok := getIP()
        if !ok {
            return
        }
        dconn, err := net.Dial("tcp", ip)
        if err != nil {
            fmt.Printf("连接%v失败:%v
    ", ip, err)
            return
        }
        ExitChan := make(chan bool, 1)
        go func(sconn net.Conn, dconn net.Conn, Exit chan bool) {
            _, err := io.Copy(dconn, sconn)
            if err != nil {
                fmt.Printf("往%v发送数据失败:%v
    ", ip, err)
            }
            ExitChan <- true
        }(sconn, dconn, ExitChan)
        go func(sconn net.Conn, dconn net.Conn, Exit chan bool) {
            _, err := io.Copy(sconn, dconn)
            if err != nil {
                fmt.Printf("从%v接收数据失败:%v
    ", ip, err)
            }
            ExitChan <- true
        }(sconn, dconn, ExitChan)
        <-ExitChan
        dconn.Close()
    }
    
    func getIP() (string, bool) {
        lock.Lock()
        defer lock.Unlock()
    
        if len(trueList) < 1 {
            return "", false
        }
        ip := trueList[0]
        trueList = append(trueList[1:], ip)
        return ip, true
    }
  • 相关阅读:
    122. 买卖股票的最佳时机 II
    45. 跳跃游戏 II
    134. 加油站
    55. 跳跃游戏
    714. 买卖股票的最佳时机含手续费
    121. 买卖股票的最佳时机
    860. 柠檬水找零
    开发环境安装合集(部分搬运)
    javascript的单例模式
    javascript 工厂模式
  • 原文地址:https://www.cnblogs.com/mignet/p/go_transfer.html
Copyright © 2011-2022 走看看