V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
8520ccc
V2EX  ›  问与答

能否同个端口同时和多个服务器 IP:端口建立 TCP 链接

  •  
  •   8520ccc · 309 天前 via iPhone · 1688 次点击
    这是一个创建于 309 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我知道,理论上,原理上一定能实现

    因为四元祖是:server ip port client ip port

    那么,有没有支持这个功功能得系统或者方案呢?

    最好是 GO 能用的

    11 条回复    2024-01-17 12:34:05 +08:00
    serafin
        1
    serafin  
       309 天前
    理论不行。 在 TCP 协议中,一个端口只能绑定到一个服务器 IP:端口组合。除非你说的同时是快速轮训不同的服务器 IP:端口组合,达到看上去同时的效果。
    zealic
        2
    zealic  
       309 天前   ❤️ 1
    现成方案没有,可以基于 gvisor 重写 tcp netstack ,实现 Reverse Dial

    https://github.com/google/gvisor/tree/master/pkg/tcpip
    d7b3e8c0094870b9
        3
    d7b3e8c0094870b9  
       309 天前 via iPhone
    package main

    import (
    "fmt"
    "net"
    "sync"
    )

    func connectToServer(serverAddr string, wg *sync.WaitGroup) {
    defer wg.Done()

    // 与服务器建立连接
    conn, err := net.Dial("tcp", serverAddr)
    if err != nil {
    fmt.Printf("Cannot connect to server %s: %v\n", serverAddr, err)
    return
    }
    defer conn.Close()

    fmt.Printf("Connected to server: %s\n", serverAddr)
    // 这里可以添加与服务器通信的代码
    // ...
    }

    func main() {
    var wg sync.WaitGroup

    // 服务器 1 地址
    server1 := "server1:8080"
    // 服务器 2 地址
    server2 := "server2:8080"

    // 同时建立两个连接
    wg.Add(2)
    go connectToServer(server1, &wg)
    go connectToServer(server2, &wg)

    // 等待所有 Goroutines 完成
    wg.Wait()

    fmt.Println("Both connections established")
    }
    Citrus
        4
    Citrus  
       309 天前 via iPhone
    目前常用的 TCP 协议栈实现应该都没做这个支持,参考 @zealic 的回答自己实现协议栈吧。
    @serafin 理论可以的,TCP 协议栈的定义是支持的。只是实现支不支持另说。
    @d7b3e8c0094870b9 GPT 生成的?你有仔细看要求么。。。
    lovelylain
        5
    lovelylain  
       309 天前 via Android
    bind 不同端口然后用 iptables snat 到同一个端口吧
    opengps
        6
    opengps  
       309 天前
    只要求同一个端口发出,那你可以尝试变化本地 ip ,这就要求你本地网卡有多 ip
    sky96111
        7
    sky96111  
       309 天前 via Android
    mtw
        8
    mtw  
       309 天前
    用 C 语言写很简单,理论上 go 语言也可以的。
    skyqqcc581
        9
    skyqqcc581  
       309 天前
    @d7b3e8c0094870b9 Cannot connect to server baidu.com: dial tcp 0.0.0.0:9999->:80: bind: address already in use
    Connected to server: qq.com
    Both connections established 这个完全不可行
    skyqqcc581
        10
    skyqqcc581  
       309 天前
    @opengps 公网 IP 时 IP 要钱的
    skyqqcc581
        11
    skyqqcc581  
       309 天前   ❤️ 1
    @sky96111 thanks 在 ubuntu 上测试成功了

    ```
    package main

    import (
    "log"

    reuse "github.com/libp2p/go-reuseport"
    )

    func main() {
    l2, err := reuse.Dial("tcp", "0.0.0.0:1234", "baidu.com:80")
    l3, err1 := reuse.Dial("tcp", "0.0.0.0:1234", "qq.com:80")
    log.Println(err, err1)
    log.Println(l2.LocalAddr())
    log.Println(l3.LocalAddr())
    if err == nil {
    l2.Close()
    }
    if err1 == nil {
    l3.Close()
    }
    }

    ```
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1075 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 19:20 · PVG 03:20 · LAX 11:20 · JFK 14:20
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.