在 Kotlin 中使用代理
Kotlin 中的代理
Kotlin 运行在 JVM 上,可以完整使用 Java API 来处理代理。此外,常用的 Kotlin 库(OkHttp、Ktor)也提供了各自便捷的代理配置 API。
OkHttp(推荐)
OkHttp 是 Kotlin/Android 中最流行的 HTTP 客户端。
HTTP 代理
import okhttp3.OkHttpClient
import okhttp3.Request
import java.net.InetSocketAddress
import java.net.Proxy
val proxy = Proxy(
Proxy.Type.HTTP,
InetSocketAddress("proxy_ip", 8080)
)
val client = OkHttpClient.Builder()
.proxy(proxy)
.build()
val request = Request.Builder()
.url("https://httpbin.org/ip")
.build()
client.newCall(request).execute().use { response ->
println(response.body?.string())
}
SOCKS5 代理
val proxy = Proxy(
Proxy.Type.SOCKS,
InetSocketAddress("proxy_ip", 1080)
)
val client = OkHttpClient.Builder()
.proxy(proxy)
.build()
身份验证
import okhttp3.Authenticator
import okhttp3.Credentials
import okhttp3.Route
val proxyAuthenticator = Authenticator { _: Route?, response: okhttp3.Response ->
val credential = Credentials.basic("username", "password")
response.request.newBuilder()
.header("Proxy-Authorization", credential)
.build()
}
val client = OkHttpClient.Builder()
.proxy(proxy)
.proxyAuthenticator(proxyAuthenticator)
.build()
Ktor Client
Ktor 是 JetBrains 推出的异步框架,原生支持 Kotlin。
HTTP 代理
import io.ktor.client.*
import io.ktor.client.engine.okhttp.*
import io.ktor.client.request.*
import io.ktor.client.statement.*
import java.net.InetSocketAddress
import java.net.Proxy
val client = HttpClient(OkHttp) {
engine {
proxy = Proxy(
Proxy.Type.HTTP,
InetSocketAddress("proxy_ip", 8080)
)
}
}
suspend fun main() {
val response: HttpResponse = client.get("https://httpbin.org/ip")
println(response.bodyAsText())
client.close()
}
使用 CIO 引擎
import io.ktor.client.*
import io.ktor.client.engine.cio.*
import io.ktor.client.request.*
import io.ktor.client.statement.*
val client = HttpClient(CIO) {
engine {
proxy = io.ktor.client.engine.ProxyBuilder.http("http://proxy_ip:8080")
}
}
通过 Ktor 使用 SOCKS
val client = HttpClient(OkHttp) {
engine {
proxy = Proxy(
Proxy.Type.SOCKS,
InetSocketAddress("proxy_ip", 1080)
)
}
}
Java Proxy API
标准的 Java API 在 Kotlin 中同样可用:
import java.net.HttpURLConnection
import java.net.InetSocketAddress
import java.net.Proxy
import java.net.URL
val proxy = Proxy(Proxy.Type.HTTP, InetSocketAddress("proxy_ip", 8080))
val url = URL("https://httpbin.org/ip")
val connection = url.openConnection(proxy) as HttpURLConnection
// 身份验证
val encoded = java.util.Base64.getEncoder()
.encodeToString("user:pass".toByteArray())
connection.setRequestProperty("Proxy-Authorization", "Basic $encoded")
connection.inputStream.bufferedReader().use { reader ->
println(reader.readText())
}
代理轮换
import okhttp3.OkHttpClient
import okhttp3.Request
import java.net.InetSocketAddress
import java.net.Proxy
data class ProxyConfig(val host: String, val port: Int, val user: String, val pass: String)
val proxies = listOf(
ProxyConfig("proxy1", 8080, "user", "pass"),
ProxyConfig("proxy2", 8080, "user", "pass"),
ProxyConfig("proxy3", 8080, "user", "pass"),
)
fun getClient(proxyConfig: ProxyConfig): OkHttpClient {
val proxy = Proxy(Proxy.Type.HTTP, InetSocketAddress(proxyConfig.host, proxyConfig.port))
return OkHttpClient.Builder()
.proxy(proxy)
.proxyAuthenticator { _, response ->
val credential = okhttp3.Credentials.basic(proxyConfig.user, proxyConfig.pass)
response.request.newBuilder()
.header("Proxy-Authorization", credential)
.build()
}
.build()
}
fun fetchWithRotation(url: String): String? {
val proxy = proxies.random()
val client = getClient(proxy)
val request = Request.Builder().url(url).build()
return try {
client.newCall(request).execute().use { it.body?.string() }
} catch (e: Exception) {
println("Failed with ${proxy.host}: ${e.message}")
null
}
}
Android 平台注意事项
Android 系统代理
在 Android 上,您可以使用系统代理:
val proxyHost = System.getProperty("http.proxyHost")
val proxyPort = System.getProperty("http.proxyPort")?.toIntOrNull()
NetworkSecurityConfig
要在 Android 7+ 上使用代理,需要配置 network_security_config.xml 以允许明文(cleartext)流量(如果代理为 HTTP)。
Retrofit + 代理
val proxy = Proxy(Proxy.Type.HTTP, InetSocketAddress("proxy_ip", 8080))
val okHttpClient = OkHttpClient.Builder().proxy(proxy).build()
val retrofit = Retrofit.Builder()
.baseUrl("https://api.example.com/")
.client(okHttpClient)
.addConverterFactory(GsonConverterFactory.create())
.build()
超时与相关设置
import java.util.concurrent.TimeUnit
val client = OkHttpClient.Builder()
.proxy(proxy)
.connectTimeout(10, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.writeTimeout(10, TimeUnit.SECONDS)
.retryOnConnectionFailure(true)
.build()
总结
Kotlin 提供了多种使用代理的方式:OkHttp 简单且性能出色,Ktor 适合基于协程的异步方案,标准 Java API 则用于兼容性场景。在 Android 开发中,OkHttp + Retrofit 是业界标准。以上所有方案都支持带身份验证的 HTTP 和 SOCKS5 代理。
