类似反向代理,通过一台有公网 IP 的服务器中转使我们可以访问到 没有公网 IP 的服务
放张容易理解的图:
From: https://github.com/aploium/shootback
我自己的电脑 A 连入了内网,但不能直接连入互联网 或者说 网速有限制不能满足需求;
但外界的服务器 B 可以连上 A 提供的 http 服务 (由内网其他服务器转发),但仅仅支持普通的 http,不支持 websocket
需求是在这种情况下通过 B 向 A 发起 http 请求的方式实现 A 的连入互联网
A 想上网,但只能靠 B 向 A 主动发起 http 连接
B 发起 http 请求 和 A 的回应 必须完整后 才能抵达对方(长连接无效)
frp、上图的 shootback 的客户端和服务端都需要 tcp 连接,并不能支持 http 协议的连接
https://github.com/sensepost/reGeorg
reGeorg 可以把 web 服务变为 socks 代理,但本质上还是 B 通过 A 的方式去请求 A 能得到的资源(比如说 A 所在的内网资源),我这个需求是要反过来 A 通过 B 去访问外网
A 实现一个 socks5 代理 和 http 服务器,B 实现 http 客户端; 使用$$tap 来让上层应用走 A 的 socks5 代理上网
B 轮询 A 问有没有请求,如果有就记下来,与真实目标建立 socket 连接,下次 http 请求的时候带上请求的相应内容
目前我的实现是 B 开 100 个线程轮询 A,A 在 10s 内如果有请求就在 http 响应中给出请求内容(A 的 socket send 的内容)和 request id ; 10s 超时就让 B 继续轮询; B 收到回应后检查 request id 对应的 socket、往 socket 里面 send ; B 对每个 socket 循环 recv,有内容就发起对 A 的 http 请求,带上 request id 和 socket recv 得到内容
但在高并发的时候 A 与 B 之间的 http 通讯并不一定稳定,可能请求失败(丢包)、后来的请求先到达对方(乱序);感觉就要实现一个 http 之上的 tcp 协议。。。
多线程写起来也没把握,写炸了也不明不白;这种情景下的实现能不能用 select 或者 epoll
还有一个性能上的问题:这种情景下 socket send 一次相对原生的 tcp 而言代价就很高,但 socks5 代理 recv 以及 socket 连真实服务器 recv 可能不需要交互接连两次 /多次,这时候可以合并多次 recv 得到的内容以减轻代价(如下载大文件);但在 https 握手这种交互情况下,为了减轻延迟 recv 了一次就需要马上从真实服务器得到回应 上层应用才会发起下一个包,如果设计成每隔 1s 才发一次包就意味着 https 握手就需要 3~4s 才能完成。 可不可能实现智能判断 socket 一次 recv 后下一次 recv 多久后会到达?
问问大佬们有啥项目实现了这种情景 或者 给点建议
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.