V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
hkshawn
V2EX  ›  程序员

请教,用 go 写一个具有特殊功能的端口转发思路

  •  
  •   hkshawn · 2022-08-22 07:10:21 +08:00 · 1879 次点击
    这是一个创建于 834 天前的主题,其中的信息可能已经有所发展或是发生改变。

    本来用 mqtt 写了一个,目的是具有滑动窗口功能,保持长连接,但是发现小坑太多了,怎么也爬不完,所以请教各路大神,如果用 io.copy 的思路,可以完成吗? 核心就是如果 client 网络断开几秒,然后恢复连接,长连接不会被断开,因为我之前看到有一片文献,写的是基于 io.copy 的具有滑动窗口的下载,所以就有了这个想法,自学小白刚入门,可能想法比较天真,希望有大佬能指点一下!拴 q

    10 条回复    2022-09-09 16:48:34 +08:00
    whitehack
        1
    whitehack  
       2022-08-22 10:18:28 +08:00
    > 核心就是如果 client 网络断开几秒,然后恢复连接

    已我的理解 你需要再做个代理客户端了,做个简单的鉴权.
    不然无法确定新的客户端连接上来 对应的是哪个长连接.

    除非只有一个连接 你自己一个人用


    然后才是考虑你的滑动窗口功能 ,你的想法没有什么问题.
    hkshawn
        2
    hkshawn  
    OP
       2022-08-22 10:32:19 +08:00
    @whitehack
    也就是用 io.copy 是可以的是吧,简单的说就是利用 io.copy 做基于滑动窗口的端口转发,如果 io.copy 要是能实现,理论上说要比 mqtt 简单的太多了,而且使用场景也多很多,稳定性也会极大提升!
    cs8425
        3
    cs8425  
       2022-08-22 10:45:55 +08:00
    没看懂什么叫"io.copy 的思路"
    io.Copy 简单讲不就读 A 写 B 重复循环吗
    gogogo2000
        4
    gogogo2000  
       2022-08-22 11:01:48 +08:00
    和你使用什么来实现转发没有任何关系,你可以使用任何现有的库来实现转发。
    保持客户端断开重连后依然能维持原有连接的核心是不使用 tcp 或 udp 的基于握手和端口的连接机制,而是自己实现连接识别(例如为每个连接分配 id ,重连后 id 不变),然后客户端和服务端两侧实现各自的 tcp/udp 连接保持。

    应用->客户端->客户端缓冲->带 id 的连接->服务端识别 id->服务端->外部
    hkshawn
        5
    hkshawn  
    OP
       2022-08-22 11:06:09 +08:00
    @gogogo2000
    应用场景跟你所说的十分+-
    hkshawn
        6
    hkshawn  
    OP
       2022-08-22 11:07:40 +08:00
    @gogogo2000
    应用场景跟你所说的十分相似,但是作为端口转发,又需要判断应用的长连接是否保持就很困难,举个例子就是 如果收到 eof 就很难处理
    hkshawn
        7
    hkshawn  
    OP
       2022-08-22 11:08:17 +08:00
    @cs8425
    io.copy 就是 go 的一个底层包 其实就是 读 a 写 b 重复循环
    rev1si0n
        8
    rev1si0n  
       2022-08-22 14:47:32 +08:00
    如果你是通过你写的隧道转发任意其他协议,客户端连接断了,你虽然和远端的被转发服务保持着连接,但是客户端它认为自己断了,然后和你重新沟通,怎么把他们接起来。如果是特定协议且沟通过程没有什么变数的话,倒是有可能。
    hkshawn
        9
    hkshawn  
    OP
       2022-08-22 16:10:58 +08:00
    @rev1si0n
    难点是不好判断客户端是否断开了,客户端是长连接还是短链接.
    gogogo2000
        10
    gogogo2000  
       2022-09-09 16:48:34 +08:00
    @hkshawn 并不难,方法有很多,举个例子,你可以实现一个独立的控制连接,这个控制连接专门用于发送连接的关闭信息。当客户端断开连接后控制连接发送该连接关闭的信息,服务端就可以安全的关闭对应的对外连接了,反之则认为客户端是异常断开,服务端应该保留该连接等待重连(或超时)
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1193 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 18:30 · PVG 02:30 · LAX 10:30 · JFK 13:30
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.