网络代理的原理

网络代理的原理

马草原 873 2023-06-04

网络代理的原理

相信对于各位程序员👨🏻‍💻来说梯子是少不了的,但是你有了解过梯子是怎么运作的吗,在代码中又如何使用梯子呢?最近在本地调试ChatGPT的接口时需要频繁使用代理索性来看一下代理的运作方式。

网络代理软件的原理

基本原理

GFW

一个网络代理软件首先要在本地的电脑或者其他设备有一个客户端proxy client,其次还需要在远程服务器(通常是海外)部署一个服务端proxy serverclientserver之间的通信需要经过加密。我们平时听到的Sock5协议实际上是图中红圈圈住的部分,即浏览器和proxy client之间用的,该协议的作用是运行浏览器告诉proxy server自己要访问哪个地方

全局视角

proxyserver

  • Proxy Client:代理客户端
    • xx协议端口:客户端会监听多个端口,每个端口对应一种代理协议,浏览器根据设定好的代理协议访问指定的端口
    • xx协议协议栈:客户端接收到浏览器访问后会调用对应的协议栈处理,比如Sock5协议栈就会和浏览器执行一次握手+认证后再做代理工作
    • Tunnels:代理隧道,当协议栈需要访问代理服务器(proxy server)时,会选择一条代理隧道作为通道,通过该隧道和代理服务器交换数据,数据的加密工作就是在这里完成的。代理隧道可以为多条或者一条,本地的请求将复用这些代理隧道,请求的响应通过id区分,比如当隧道只有一条时,本地电脑的ChromeSafari的请求数据都会走这一条隧道,但是各自的请求/响应数据包都会打上id,代理客户端会根据数据包的id将数据派发给对应的浏览器。
  • Proxy Server:代理服务端
    • Tunnel事件处理中心:代理服务器在收到来自代理客户端的数据包后,会解析数据包并执行其中包含的指令,比如建立和Google.com的连接
    • duplex handler:代理服务器与目标服务器之间的双工通信,负责:
      • 收到代理客户端发过来的数据后向目标服务器写
      • 收到目标服务器的数据后向代理客户端写

如何在代码中使用

我们如果要在代码中调用需要代理的接口(比如调用爆火的ChatGPT),如果你不用梯子那只能通过代码中设置代理到海外才行,如果你本地有梯子多数情况下在代码中不生效,除非开全局代理,全局代理会导致使用国内的软件巨卡(发个微信都转圈圈🙄)。
这时候最好的办法就是在代码里需要用代理的地方手动设置,这样还有个好处就是可以有多个代理 在代码中轮询(可以避免基于IP的限流。。)

以OKHTTP为例调用Google的接口:

public static void proxyTest() {
  // 创建代理服务器
  Proxy proxy = new Proxy(Proxy.Type.SOCKS, new InetSocketAddress("127.0.0.1", 15733));

  // 创建 OkHttpClient 实例,并设置代理
  OkHttpClient client = new OkHttpClient.Builder()
    .proxy(proxy)
    .build();

  MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
  RequestBody body = RequestBody.create(mediaType, "q=macaoyuan");
  Request request = new Request.Builder()
    .url("https://google-translate1.p.rapidapi.com/language/translate/v2/detect")
    .post(body)
    .build();

  try {
    Response response = client.newCall(request).execute();
    assert response.body() != null;
    System.out.println(response.body().string());
  } catch (IOException e) {
    System.out.println("An error occurred: " + e.getMessage());
  }
}

响应:

{
	"message": "Invalid API key."
}

可以看到成功响应了结果,这个报错是因为没有Google接口的API key但是我们只要证明网络是连通的即可。