You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java使用SOCKS代理而非HTTP代理时连接报错的解决咨询

问题描述

尝试通过代理连接服务器,设置代理的代码如下:

try {
    System.setProperty("java.net.useSystemProxies", "true");
    System.out.println("detecting proxies");
    List l = null;
    try {
        l = ProxySelector.getDefault().select(new URI("https://www.google.com"));
    } catch (URISyntaxException e) {
        e.printStackTrace();
        System.out.println("Failed to list the proxy..." + e.getMessage());
    }
    if (l != null) {
        for (Iterator iter = l.iterator(); iter.hasNext();) {
            java.net.Proxy proxy = (java.net.Proxy) iter.next();
            System.out.println("proxy type: " + proxy.type());
            InetSocketAddress addr = (InetSocketAddress) proxy.address();
            if (addr == null) {
                System.out.println("No Proxy");
            } else {
                System.out.println("proxy hostname: " + addr.getHostName());
                System.setProperty("http.proxyHost", addr.getHostName());
                System.setProperty("https.proxyHost", addr.getHostName());
                System.out.println("proxy port: " + addr.getPort());
                System.setProperty("http.proxyPort", Integer.toString(addr.getPort()));
                System.setProperty("https.proxyPort", Integer.toString(addr.getPort()));
            }
        }
    }
} catch (Exception e) {
    e.printStackTrace();
}

发送请求的代码:

RequestBody body = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), jsonValue);
Request request = new Request.Builder().url(settings.getServiceUrl() + "/" + service).addHeader("Authorization", Credentials.basic(settings.getServiceUserName(), settings.getServicePassword())).post(body).build();
OkHttpClient.Builder builder =new OkHttpClient.Builder();
OkHttpClient client = builder.readTimeout(6000 * 1000, TimeUnit.MILLISECONDS)
        .writeTimeout(6000 * 1000, TimeUnit.MILLISECONDS).build();
Call call = client.newCall(request);
Response response = call.execute();

运行后抛出错误:

java.net.SocketException: Malformed reply from SOCKS server
at java.net.SocksSocketImpl.readSocksReply(Unknown Source)
at java.net.SocksSocketImpl.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at okhttp3.internal.platform.Platform.connectSocket(Platform.java:130)
at okhttp3.internal.connection.RealConnection.connectSocket(RealConnection.java:263)
at okhttp3.internal.connection.RealConnection.connectTunnel(RealConnection.java:235)
at okhttp3.internal.connection.RealConnection.connect(RealConnection.java:177)
at okhttp3.internal.connection.ExchangeFinder.findConnection(ExchangeFinder.java:224)
解决方法

该错误的核心原因是用HTTP代理的配置逻辑处理SOCKS代理,两种代理协议不兼容导致握手失败。以下是针对性解决步骤:

1. 区分代理类型适配配置

ProxySelector可能返回SOCKS类型代理,但你当前代码统一按HTTP/HTTPS代理设置系统属性,需修改逻辑区分处理:

try {
    System.setProperty("java.net.useSystemProxies", "true");
    System.out.println("detecting proxies");
    List<Proxy> proxyList = ProxySelector.getDefault().select(new URI(settings.getServiceUrl() + "/" + service));
    if (proxyList != null) {
        for (Proxy proxy : proxyList) {
            System.out.println("proxy type: " + proxy.type());
            InetSocketAddress addr = (InetSocketAddress) proxy.address();
            if (addr == null) {
                System.out.println("No Proxy");
                continue;
            }
            String host = addr.getHostName();
            int port = addr.getPort();
            if (proxy.type() == Proxy.Type.HTTP) {
                // HTTP/HTTPS代理设置对应系统属性
                System.setProperty("http.proxyHost", host);
                System.setProperty("https.proxyHost", host);
                System.setProperty("http.proxyPort", String.valueOf(port));
                System.setProperty("https.proxyPort", String.valueOf(port));
            } else if (proxy.type() == Proxy.Type.SOCKS) {
                // SOCKS代理需单独设置专用属性
                System.setProperty("socksProxyHost", host);
                System.setProperty("socksProxyPort", String.valueOf(port));
                // 若SOCKS代理需要认证,补充以下配置:
                // System.setProperty("java.net.socks.username", "your-socks-username");
                // System.setProperty("java.net.socks.password", "your-socks-password");
            }
        }
    }
} catch (Exception e) {
    e.printStackTrace();
}

2. 直接给OkHttpClient配置代理(推荐)

系统属性是全局生效,不如直接在OkHttpClient中配置对应代理,更灵活且避免冲突:

RequestBody body = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), jsonValue);
Request request = new Request.Builder()
        .url(settings.getServiceUrl() + "/" + service)
        .addHeader("Authorization", Credentials.basic(settings.getServiceUserName(), settings.getServicePassword()))
        .post(body)
        .build();

OkHttpClient.Builder builder = new OkHttpClient.Builder();

// 获取适配目标URL的代理列表
List<Proxy> proxyList = ProxySelector.getDefault().select(new URI(settings.getServiceUrl() + "/" + service));
if (!proxyList.isEmpty()) {
    Proxy proxy = proxyList.get(0); // 取第一个可用代理,可根据实际调整选择逻辑
    builder.proxy(proxy);
    // 若为需要认证的SOCKS代理,添加认证器
    if (proxy.type() == Proxy.Type.SOCKS) {
        builder.proxyAuthenticator(new Authenticator() {
            @Override
            public Request authenticate(Route route, Response response) throws IOException {
                String credential = Credentials.basic("socks-username", "socks-password");
                return response.request().newBuilder()
                        .header("Proxy-Authorization", credential)
                        .build();
            }
        });
    }
}

OkHttpClient client = builder
        .readTimeout(6000 * 1000, TimeUnit.MILLISECONDS)
        .writeTimeout(6000 * 1000, TimeUnit.MILLISECONDS)
        .build();

Call call = client.newCall(request);
Response response = call.execute();

3. 排查代理服务本身问题

  • 确认SOCKS代理服务器地址、端口正确,服务处于运行状态
  • 用工具测试代理可用性,比如执行curl -x socks5://proxy-host:port your-service-url验证是否能正常访问目标服务

内容的提问来源于stack exchange,提问作者kiran

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 14:01:30