golang 实现tcp转发代理的方法
作者:JieLinDee 发布时间:2023-08-06 02:46:55
标签:golang,tcp,转发代理
我就废话不多说了,直接上代码吧:
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("后端IP和端口不能空,或者无效")
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\n", 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\n", ip, err)
return
}
ExitChan := make(chan bool, 1)
go func(sconn net.Conn, dconn net.Conn, Exit chan bool) {
_, err := io.Copy(dconn, sconn)
fmt.Printf("往%v发送数据失败:%v\n", ip, err)
ExitChan <- true
}(sconn, dconn, ExitChan)
go func(sconn net.Conn, dconn net.Conn, Exit chan bool) {
_, err := io.Copy(sconn, dconn)
fmt.Printf("从%v接收数据失败:%v\n", 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
}
来源:https://blog.csdn.net/fyxichen/article/details/51505542


猜你喜欢
- json 作为一种通用的编解码协议,可阅读性上比 thrift,protobuf 等协议要好一些,同时编码的 size 也会比 xml 这类
- 前言cookie:在网站中,http请求是无状态的。也就是说即使第一次和服务器连接后并且登录成功后,第二次请求服务器依然不能知道当前请求是哪
- 前言:Python smtplib 教程:展示了如何使用 smtplib 模块在 Python 中发送电子邮件。 要发送电子邮件,我们使用
- 废话不多说了,直接给大家贴代码了,具体代码如下所示:-- 开窗函数:在结果集的基础上进一步处理(聚合操作)-- Over函数,添加一个字段显
- vuex的理论知识就不多提了,官网上已经有明确的讲解。用一个简单的例子来描述一下基本的用法:第一步:npm install vuex –sa
- 例如:from multiprocessing import Pooldef f(x):return x*xpool = Pool(proc
- 游标(Cursor)是处理数据的一种方法,为了查看或者处理结果集中的数据,游标提供了在结果集中一次以行或者多行前进或向后浏览数据的能力。我们
- OOM全称"Out Of Memory",即内存溢出。内存溢出已经是软件开发历史上存在了近40年的“老大难”问题。在操作
- 父组件处理:<template> <div class="wrap">
- 这个东西很重要,可以经常用在项目当中,所以我们单独拿出来进行讲解。在使用它之前我们需要导包: go get golang.org/
- 代码如下:from PIL import Image #图像处理模块import numpy as npa = np.asarr
- 当你碰到下面的asp错误提示时,说明你asp运行脚本超时了! Active Serv
- 1. 扩展Tensor维度相信刚接触Pytorch的宝宝们,会遇到这样一个问题,输入的数据维度和实验需要维度不一致,输入的可能是2维数据或3
- 本文实例为大家分享了python tornado微信开发的具体代码,供大家参考,具体内容如下#微信入门代码#!/usr/bin/env py
- composer更新依赖包compoesr 的 require/update 都可以更新指定的依赖包 (升级 / 降级)。require 更
- 你需要添加两个按钮:一个按钮使所有英雄都可以死亡,而另一个按钮使所有英雄永生。由于它会影响所有英雄,而与选择无关,因此这需要一个单独的按钮,
- 本文实例讲述了Python实现字典按照value进行排序的方法。分享给大家供大家参考,具体如下:先说几个解决的方法,具体的有时间再细说d =
- 为什么PHP7的性能可以提高这么多?1. JIT 2. Zval的改变 3. 内部类型zend_string 4. PHP数组的变化(Has
- 前言:测试过程中获取App相关log后,如何快速找出crash的部分,并导出到新的文件呢?感兴趣的话,继续往下看吧~思路:遍历多个日志文件,
- 这些天因为有数据割接的需求,于是有要写关于批量更新的程序。我们的数据库使用的是SQLSERVER2005,碰到了一些问题来分享下。首先注意S