Android:使用HttpURLConnection进行网络请求时SocketException问题

使用HttpURLConnection进行网络请求时,通常用法如下:

//创建URL对象
URL url = new URL("https://www.baidu.com");
// 根据url 发送 http的请求
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
// 设置请求的方式
conn.setRequestMethod("GET");
//设置超时时间
conn.setConnectTimeout(5000);
// 得到服务器返回的响应码
int code = conn.getResponseCode();
//请求网络成功后返回码是200
if (code == 200) {
//获取输入流
InputStream is = conn.getInputStream();
}

若直接运行包含以上代码段的程序,会出现以下错误信息:

W/System.err: java.lang.SecurityException: Permission denied (missing INTERNET permission?)
        at java.net.Inet6AddressImpl.lookupHostByName(Inet6AddressImpl.java:150)
        at java.net.Inet6AddressImpl.lookupAllHostAddr(Inet6AddressImpl.java:103)
        at java.net.InetAddress.getAllByName(InetAddress.java:1152)
        at com.android.okhttp.Dns$1.lookup(Dns.java:41)
        at com.android.okhttp.internal.http.RouteSelector.resetNextInetSocketAddress(RouteSelector.java:178)
        at com.android.okhttp.internal.http.RouteSelector.nextProxy(RouteSelector.java:144)
W/System.err:     at com.android.okhttp.internal.http.RouteSelector.next(RouteSelector.java:86)
        at com.android.okhttp.internal.http.StreamAllocation.findConnection(StreamAllocation.java:176)
        at com.android.okhttp.internal.http.StreamAllocation.findHealthyConnection(StreamAllocation.java:128)
        at com.android.okhttp.internal.http.StreamAllocation.newStream(StreamAllocation.java:97)
        at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:289)
        at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:232)
        at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:465)
        at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:411)
W/System.err:     at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:542)
        at com.example.imageview.MainActivity$2.run(MainActivity.java:66)
    Caused by: android.system.GaiException: android_getaddrinfo failed: EAI_NODATA (No address associated with hostname)
        at libcore.io.Linux.android_getaddrinfo(Native Method)
        at libcore.io.ForwardingOs.android_getaddrinfo(ForwardingOs.java:74)
        at libcore.io.BlockGuardOs.android_getaddrinfo(BlockGuardOs.java:200)
        at libcore.io.ForwardingOs.android_getaddrinfo(ForwardingOs.java:74)
        at java.net.Inet6AddressImpl.lookupHostByName(Inet6AddressImpl.java:135)
    	... 15 more
    Caused by: android.system.ErrnoException: android_getaddrinfo failed: EPERM (Operation not permitted)

根据报错信息,然后百度可知,请求网络需要在配置文件AndroidManifest.xml中添加权限:

<uses-permission android:name="android.permission.INTERNET" />

添加以上权限,再次运行程序,又出现以下错误,错误位置就是在getResponseCode();方法处

W/System.err: java.net.SocketException: socket failed: EPERM (Operation not permitted)
W/System.err:     at java.net.Socket.createImpl(Socket.java:492)
        at java.net.Socket.getImpl(Socket.java:552)
        at java.net.Socket.setSoTimeout(Socket.java:1180)
        at com.android.okhttp.internal.io.RealConnection.connectSocket(RealConnection.java:143)
        at com.android.okhttp.internal.io.RealConnection.connect(RealConnection.java:116)
W/System.err:     at com.android.okhttp.internal.http.StreamAllocation.findConnection(StreamAllocation.java:186)
        at com.android.okhttp.internal.http.StreamAllocation.findHealthyConnection(StreamAllocation.java:128)
        at com.android.okhttp.internal.http.StreamAllocation.newStream(StreamAllocation.java:97)
        at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:289)
        at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:232)
        at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:465)
        at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:411)
        at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:542)
        at com.example.imageview.MainActivity$2.run(MainActivity.java:66)

网上查询错误的解决方法,说不仅要添加网络访问权限,还需要添加网络状态权限,即:

 <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

添加权限后,错误仍然没有解决。
联想到以前添加权限时不仅要在配置文件中添加权限,在运行程序时,还需要在系统设置->应用与通知中添加应用的权限。
于是,运行模拟器,打开设置->应用与通知,找到当前应用,但是在权限处没有请求任何权限,可知这种方式也行不通。
在这里插入图片描述
后来,不改变程序中的代码,换一个模拟器运行,错误竟然得到了解决。
再后来又尝试着在原来的模拟器上卸载应用(长按应用图标,拖动至屏幕上方卸载),再次运行安装程序,错误也没有出现
在这里插入图片描述导致这种错误的原因可能是第一次运行程序,进行网络请求时赋予网络权限,重新给程序赋予权限时并没有卸载程序,再次运行只是重新编译,系统并没有获取到配置文件中的权限,因此需要卸载重新安装。
这可能跟权限的种类有关,以前在向内部存储器中读写信息,查看系统信息、联系人时,若第一次未添加权限,添加权限再次运行运行即可。
这次的错误也给了我一个新的感悟,在遇到权限声明甚至是其他错误信息时,若参照网络上的解决方法仍无法解决问题时,可以尝试着更换模拟器或者卸载应用再次运行,这种方法略显极端但对有些不好解决的问题却很好用。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用HTTPURLConnection发送请求,可以按照以下步骤进行: 1. 在AndroidManifest.xml文件中添加网络权限: ``` <uses-permission android:name="android.permission.INTERNET" /> ``` 2. 在子线程中使用HTTPURLConnection发送请求,例如: ``` Thread thread = new Thread(new Runnable() { @Override public void run() { try { // 创建URL对象 URL url = new URL("http://www.example.com/api"); // 打开连接 HttpURLConnection connection = (HttpURLConnection) url.openConnection(); // 设置请求方法 connection.setRequestMethod("GET"); // 设置连接超和读取超间 connection.setConnectTimeout(5000); connection.setReadTimeout(5000); // 发送请求 connection.connect(); // 获取响应码 int responseCode = connection.getResponseCode(); // 获取响应数据 InputStream inputStream = connection.getInputStream(); BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); StringBuilder response = new StringBuilder(); String line; while ((line = reader.readLine()) != null) { response.append(line); } reader.close(); inputStream.close(); String responseData = response.toString(); // 处理响应数据 } catch (Exception e) { e.printStackTrace(); } } }); thread.start(); ``` 这个例子中发送了一个GET请求,获取了http://www.example.com/api的响应数据。你可以根据需要设置请求方法、请求参数、请求头等。获取响应数据后,可以在UI线程中更新UI或者在子线程中处理响应数据。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值