用手机USB/热点给电脑共享网络时,java HTTP get请求报 java.net.SocketException: Permission denied: connect 错误的问题

本来就是简简单单的一个java发送http get请求,有两种方式。

第一种用URLConnection

 public static String get(String url) throws IOException {
        BufferedReader in = null;

        URL realUrl = new URL(url);
        // 打开和URL之间的连接
        URLConnection connection = realUrl.openConnection();
        // 设置通用的请求属性
        connection.setRequestProperty("accept", "*/*");
        connection.setRequestProperty("connection", "Keep-Alive");
        connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
        connection.setConnectTimeout(5000);
        connection.setReadTimeout(5000);
        // 建立实际的连接
        connection.connect();
        // 定义 BufferedReader输入流来读取URL的响应
        in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
        StringBuffer sb = new StringBuffer();
        String line;
        while ((line = in.readLine()) != null) {
            sb.append(line);
        }

        in.close();
        return sb.toString();
    }

第二种用java HTTP客户端:HttpGet、HttpClient、HttpResponse等

public static String httpGet(String url, String charset)
            throws HttpException, IOException {
        String json = null;
        HttpGet httpGet = new HttpGet();
        // 设置参数
        try {
            httpGet.setURI(new URI(url));
        } catch (URISyntaxException e) {
            throw new HttpException("请求url格式错误。"+e.getMessage());
        }
        // 发送请求
        HttpClient client=HttpClients.createDefault();
        HttpResponse httpResponse = client.execute(httpGet);
        // 获取返回的数据
        HttpEntity entity = httpResponse.getEntity();
        byte[] body = EntityUtils.toByteArray(entity);
        StatusLine sL = httpResponse.getStatusLine();
        int statusCode = sL.getStatusCode();
        if (statusCode == 200) {
            json = new String(body, charset);
            entity.consumeContent();
        } else {
            throw new HttpException("statusCode="+statusCode);
        }
        return json;
    }

实现类如下:

package com.tpot.DataDownload;

import org.apache.http.HttpEntity;
import org.apache.http.HttpException;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;

import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import sun.security.krb5.Config;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URI;
import java.net.URLConnection;

public class Downloader {

    public static String httpGet(String url, String charset)
            throws HttpException, IOException {
        String json = null;
        HttpGet httpGet = new HttpGet();
        // 设置参数
        try {
            httpGet.setURI(new URI(url));
        } catch (URISyntaxException e) {
            throw new HttpException("请求url格式错误。"+e.getMessage());
        }
        // 发送请求
        HttpClient client=HttpClients.createDefault();
        HttpResponse httpResponse = client.execute(httpGet);
        // 获取返回的数据
        HttpEntity entity = httpResponse.getEntity();
        byte[] body = EntityUtils.toByteArray(entity);
        StatusLine sL = httpResponse.getStatusLine();
        int statusCode = sL.getStatusCode();
        if (statusCode == 200) {
            json = new String(body, charset);
            entity.consumeContent();
        } else {
            throw new HttpException("statusCode="+statusCode);
        }
        return json;
    }

    public static String get(String url) throws IOException {
        BufferedReader in = null;

        URL realUrl = new URL(url);
        // 打开和URL之间的连接
        URLConnection connection = realUrl.openConnection();
        // 设置通用的请求属性
        connection.setRequestProperty("accept", "*/*");
        connection.setRequestProperty("connection", "Keep-Alive");
        connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
        connection.setConnectTimeout(5000);
        connection.setReadTimeout(5000);
        // 建立实际的连接
        connection.connect();
        // 定义 BufferedReader输入流来读取URL的响应
        in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
        StringBuffer sb = new StringBuffer();
        String line;
        while ((line = in.readLine()) != null) {
            sb.append(line);
        }

        in.close();
        return sb.toString();
    }

    public static void main(String[] args) throws IOException, HttpException {
//        Configer.configProxy();
        System.out.println(get("http://www.baidu.com"));
//        System.out.println(httpGet("http://px.hnsgkb.com/","utf-8"));
    }
}

然而编译运行,却发现报错permission denied:

一开始以为是环境变量的原因:https://blog.csdn.net/jiangshubian/article/details/76549073 添加了环境变量之后还是不行

然后以为是windows防火墙的原因,先将idea添加到了防火墙允许列表中,不行;然后干脆关闭防火墙,还是不行。

网上说也可能是代理的原因,如果使用代理的话可以按如下编写一个设置代理的函数configProxy,然后在发送请求前调用一下这个函数就行了:

package com.tpot.DataDownload;

import java.util.Properties;

public class Configer {
    public static void configProxy(){
        Properties prop=System.getProperties();

        prop.setProperty("proxySet","true");
        prop.setProperty("http.proxyHost","proxy.xxxx.com");
        prop.setProperty("http.proxyPort","8080");
        prop.setProperty("http.proxyUser","xxxxx");
        prop.setProperty("http.proxyPassword","xxxxx");

        prop.setProperty("https.proxyHost","proxy.xxxxx.com");
        prop.setProperty("https.proxyPort","8080");
        prop.setProperty("https.proxyUser","xxxxx");
        prop.setProperty("https.proxyPassword","xxxxx");
    }
}

但是我并没有使用任何代理啊,应该不是这个的问题,果然试着配了一下,还是不行。

那么为什么呢,我把我的代码给别人考了一份,然后在别人的机器上跑,结果跑通了!

最后发现是因为我的电脑是通过手机USB共享网络连的网,很可能是手机端有权限控制!

我的猜想是,之前看过一篇文章,说安卓中java如果要发送http请求 ,必须在manifest.xml中配置一个东西,否则安装存在权限控制:https://blog.csdn.net/shenyuemei/article/details/8003654

我猜就是因为这个,电脑通过手机联网,所以请求在经过android系统时,被android拦截!

暂时没找到更好的解决办法,所以如果想用java发送http请求的话就不要用android手机共享网络的方式上网了。。。

很好奇如果用ios给电脑共享网络,会不会存在同样的问题,下次测试一下。。

整整一个下午都在搞这,辣鸡安卓,毁我青春

猜你喜欢

转载自www.cnblogs.com/zealousness/p/9342768.html