解决:java.net.SocketException: Software caused connection abort: recv failed
前言:最近在学习 NIO 和netty 相关知识时,在bio的模式下,遇到了
java.net.SocketException: Software caused connection abort: recv failed 的问题,刚好解决了,记录一下
我是启动一个服务绑定8801端口,启动然 客户端使用 httpClient 进行发起一个get请求,如果成功请求后会输出 服务端的 "hello,nio1"的字样但时间情况报错了。
大概的意思就是 程序连接中止:接受失败,然后我就开始检查代码,用原生的
http
请求也是能正常返回的,浏览器,和crul http://localhost:8801
也是正常返回,那我就感觉很奇怪,为什么借助httpClient
就会失败呢?
网上查了下这个报错大概意思就直接意思: 客户端和服务端建立tcp的短连接,每次客户端发送一次请求, 服务端响应后关闭与客户端的连接. 如果客户端在服务端关闭连接后,没有释放连接,继续试图发送请求和接收响应. 这个时候就会出错.
于是我开始想,会不会是服务端关闭太快导致客户端正在读的时候,服务端已经关闭了,导致报错。果断在关闭的时候阻塞线程一秒试试Thread.sleep(1000)
,就解决了。 所以这个问题报错的原因就是如上面红色字体描述的那样,在我这里就是服务端关闭太快了。
示例代码:
服务端代码
package org.geekbang.netty.server;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
// 单线程的socket程序
public class HttpServer01 {
public static void main(String[] args) throws IOException {
// 开启8801端口
ServerSocket serverSocket = new ServerSocket(8801);
while (true) {
try {
Socket socket = serverSocket.accept();
service(socket);
} catch (IOException e) {
e.printStackTrace();
}
}
}
private static void service(Socket socket) {
try {
PrintWriter printWriter = new PrintWriter(socket.getOutputStream(), true);
printWriter.println("HTTP/1.1 200 OK");
printWriter.println("Content-Type:text/html;charset=utf-8");
printWriter.println("Connection: keep-alive");
String body = "hello,nio1";
// 一定要告诉他长度
printWriter.println("Content-Length: " + body.getBytes().length);
printWriter.println();
printWriter.write(body);
// 打开下面这行 Thread.sleep(1000) 代码,延迟主线程处理关闭流和soket 就解决了
// Thread.sleep(1000);
printWriter.close();
socket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
客户端代码:
package org.geekbang.netty.util;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
/**
* @author lvzb31988
* @description: HttpClient 小试牛刀
* @date 2022/3/13
*/
@Slf4j
public class HttpClientHelper {
public static CloseableHttpClient httpclient = HttpClients.createDefault();
public static String getAsString(String url) throws IOException {
HttpGet httpGet = new HttpGet(url);
// jdk7增强try 这种写法是try-with-resources resources对象需要是 AutoCloseable接口的子类
try (CloseableHttpResponse response = httpclient.execute(httpGet)) {
System.out.println("see see what get this: " + response.getStatusLine());
HttpEntity entity = response.getEntity();
return EntityUtils.toString(entity, "UTF-8");
}
}
public static String httpRequest(String requestUrl, String requestMethod, String outputStr) {
StringBuffer buffer = null;
try {
URL url = new URL(requestUrl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setRequestMethod(requestMethod);
conn.connect();
//往服务器端写内容 也就是发起http请求需要带的参数
if (null != outputStr) {
OutputStream os = conn.getOutputStream();
os.write(outputStr.getBytes("utf-8"));
os.close();
}
//读取服务器端返回的内容
InputStream is = conn.getInputStream();
InputStreamReader isr = new InputStreamReader(is, "utf-8");
BufferedReader br = new BufferedReader(isr);
buffer = new StringBuffer();
String line = null;
while ((line = br.readLine()) != null) {
buffer.append(line);
}
} catch (Exception e) {
e.printStackTrace();
}
return buffer.toString();
}
public static void main(String[] args) throws IOException {
String url = "http://www.baidu.com";
String url1 = "http://localhost:8801";
// 客户端请求 8801单线程服务:必定失败,然后会自动重新执行请求后面几次同样失败 : Software caused connection abort: recv failed
String resultString1 = HttpClientHelper.getAsString(url1);
log.info("get调用8801返回结果:{}", resultString1);
// String httpResult = HttpClientHelper.httpRequest(url, "GET", null);
// log.info("原生 http get调用返回结果:{}", httpResult);
}
}
版权声明:程序员胖胖胖虎阿 发表于 2022年9月8日 下午8:48。
转载请注明:解决:java.net.SocketException: Software caused connection abort: recv failed | 胖虎的工具箱-编程导航
转载请注明:解决:java.net.SocketException: Software caused connection abort: recv failed | 胖虎的工具箱-编程导航
相关文章
暂无评论...