当前位置: 首页 > 面试题库 >

HttpClient连接被对等方重置:套接字写入错误

蒋航
2023-03-14
问题内容

我使用httpclient 4.4发送get和post请求。我刚刚创建了一个简单的httpclient包装器,以方便使用:

    包com.u8.server.sdk;

    导入com.sun.net.httpserver.Headers;
    导入com.u8.server.log.Log;
    导入org.apache.http.Header;
    导入org.apache.http.HttpEntity;
    导入org.apache.http.HttpResponse;
    导入org.apache.http.NameValuePair;
    导入org.apache.http.client.ClientProtocolException;
    导入org.apache.http.client.HttpClient;
    导入org.apache.http.client.HttpRequestRetryHandler;
    导入org.apache.http.client.ResponseHandler;
    导入org.apache.http.client.config.RequestConfig;
    导入org.apache.http.client.entity.UrlEncodedFormEntity;
    导入org.apache.http.client.methods.HttpGet;
    导入org.apache.http.client.methods.HttpPost;
    导入org.apache.http.config.Registry;
    导入org.apache.http.config.RegistryBuilder;
    导入org.apache.http.conn.socket.ConnectionSocketFactory;
    导入org.apache.http.conn.socket.PlainConnectionSocketFactory;
    导入org.apache.http.conn.ssl.NoopH​​ostnameVerifier;
    导入org.apache.http.conn.ssl.SSLConnectionSocketFactory;
    导入org.apache.http.conn.ssl.TrustStrategy;
    导入org.apache.http.entity.ByteArrayEntity;
    导入org.apache.http.impl.client.BasicCookieStore;
    导入org.apache.http.impl.client.CloseableHttpClient;
    导入org.apache.http.impl.client.HttpClientBuilder;
    导入org.apache.http.impl.client.HttpClients;
    导入org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
    导入org.apache.http.impl.cookie.BasicClientCookie;
    导入org.apache.http.message.BasicHeader;
    导入org.apache.http.message.BasicNameValuePair;
    导入org.apache.http.protocol.HttpContext;
    导入org.apache.http.ssl.SSLContextBuilder;
    导入org.apache.http.util.EntityUtils;
    导入org.springframework.util.StringUtils;

    导入javax.net.ssl.HostnameVerifier;
    导入javax.net.ssl.SSLContext;
    导入java.io.IOException;
    导入java.io.UnsupportedEncodingException;
    导入java.net.CookiePolicy;
    导入java.net.URLEncoder;
    导入java.nio.charset.Charset;
    导入java.security.cert.CertificateException;
    导入java.security.cert.X509Certificate;
    导入java.util.ArrayList;
    导入java.util.Iterator;
    导入java.util.List;
    导入java.util.Map;

    / **
     *由ant在2015/10/12创建。
     * /
    公共类UHttpAgent {

        private int connectTimeout = 5000; // 5秒
        private int socketTimeout = 5000; // 5秒
        private int maxTotalConnections = 200;

        私有静态UHttpAgent实例;

        私有CloseableHttpClient httpClient;

        私人UHttpAgent(){

        }

        公共静态UHttpAgent getInstance(){
            if(instance == null){
                实例=新的UHttpAgent();

            }
            返回实例;
        }

        公共静态UHttpAgent newInstance(){
            返回新的UHttpAgent();
        }


        公共字符串get(String url,Map params){

            返回get(url,null,params,“ UTF-8”);
        }


        公共字符串发布(字符串url,地图参数){

            返回post(url,null,params,“ UTF-8”);
        }


        public String get(String url,Map headers,Map params,String encoding){

            if(this.httpClient == null){
                在里面();
            }

            字符串fullUrl = url;
            字符串urlParams = parseGetParams(参数,编码);

            如果(urlParams!= null)
            {
                如果(url.contains(“?”))
                {
                    fullUrl = url +“&” + urlParams;
                }
                其他
                {
                    fullUrl =网址+“?” + urlParams;
                }
            }

            Log.d(“完整网址为” + fullUrl);
            HttpGet getReq =新的HttpGet(fullUrl.trim());
            getReq.setHeaders(parseHeaders(headers));
            ResponseHandler responseHandler = new ResponseHandler(){
                @Override
                public String handleResponse(HttpResponse httpResponse)引发IOException {
                    HttpEntity实体= httpResponse.getEntity();
                    返回实体!= null?EntityUtils.toString(entity):null;
                }
            };

            尝试{

                字符串res = httpClient.execute(getReq,responseHandler);

                返回资源;

            } catch(Exception e){
                e.printStackTrace();
            }最后{
                getReq.releaseConnection();
            }

            返回null;
        }


        公共字符串发布(字符串url,地图标题,地图参数,字符串编码){

            列表对= new ArrayList();
            if(params!= null){

                for(字符串键:params.keySet()){
                    pair.add(新的BasicNameValuePair(key,params.get(key)));
                }
            }

            返回post(URL,headers,new UrlEncodedFormEntity(pairs,Charset.forName(encoding)));
        }


        公共字符串发布(字符串url,地图标题,HttpEntity实体){

            if(this.httpClient == null){
                在里面();
            }

            HttpPost httpPost =新的HttpPost(url);
            httpPost.setHeaders(parseHeaders(headers));
            httpPost.setEntity(entity);

            ResponseHandler responseHandler = new ResponseHandler(){
                @Override
                public String handleResponse(HttpResponse httpResponse)引发IOException {
                    HttpEntity实体= httpResponse.getEntity();
                    返回实体!= null?EntityUtils.toString(entity):null;
                }
            };

            尝试{


                字符串正文= httpClient.execute(httpPost,responseHandler);

                返回身体

            } catch(IOException e){
                e.printStackTrace();
            }最后{
                httpPost.releaseConnection();
            }

            返回null;

        }


        私人标头[] parseHeaders(地图标头){
            if(null ==标头|| headers.isEmpty()){
                返回getDefaultHeaders();
            }

            Header [] hs = new BasicHeader [headers.size()];
            int i = 0;
            for(字符串键:headers.keySet()){
                hs [i] = new BasicHeader(key,headers.get(key));
                i ++;
            }

            返回hs;
        }


        私人标头[] getDefaultHeaders(){
            Header [] hs = new BasicHeader [2];
            hs [0] = new BasicHeader(“ Content-Type”,“ application / x-www-form-urlencoded”);
            hs [1] = new BasicHeader(“ User-Agent”,“ Mozilla / 5.0(Windows NT 6.3; WOW64)AppleWebKit / 537.36(KHTML,如Gecko)Chrome / 33.0.1750.146 Safari / 537.36”);
            返回hs;
        }


        私有字符串parseGetParams(地图数据,字符串编码){
            if(data == null || data.size()keyItor = data.keySet()。iterator();
            while(keyItor.hasNext()){
                字符串键= keyItor.next();
                字符串val = data.get(key);

                尝试{
                    result.append(key).append(“ =”)。append(URLEncoder.encode(val,encoding).replace(“ +”,“%2B”))。append(“&”);
                } catch(UnsupportedEncodingException e){
                    e.printStackTrace();
                }
            }

            返回result.deleteCharAt(result.length()-1).toString();

        }


        私人无效init(){

            RequestConfig requestConfig = RequestConfig.custom()
                    .setConnectTimeout(connectTimeout)
                    .setSocketTimeout(socketTimeout)
                    .setExpectContinueEnabled(true)
                    .setAuthenticationEnabled(true)
                    。建立();

            HttpRequestRetryHandler retryHandler = new HttpRequestRetryHandler(){
                @Override
                public boolean retryRequest(IOException e,int retryNum,HttpContext httpContext){

                    if(retryNum> = 3){
                        返回false;
                    }


                    if(e instanceof org.apache.http.NoHttpResponseException
                            || org.apache.http.client.ClientProtocolException的实例
                            || e instanceof java.net.SocketException){

                        返回true;
                    }

                    返回false;
                }
            };


            尝试{

                SSLContext sslContext =新的SSLContextBuilder()。loadTrustMaterial(空,新的TrustStrategy(){

                    @Override
                    public boolean isTrusted(X509Certificate [] chain,String authType)抛出CertificateException {
                        返回true;
                    }
                })。建立();

                HostnameVerifier hostnameVerifier = NoopH​​ostnameVerifier.INSTANCE;
                SSLConnectionSocketFactory sslFactory =新的SSLConnectionSocketFactory(sslContext,hostnameVerifier);

                注册表socketFactoryRegistry = RegistryBuilder.create()
                        .register(“ http”,PlainConnectionSocketFactory.getSocketFactory())
                        .register(“ https”,sslFactory)
                        。建立();

                PoolingHttpClientConnectionManager connMgr =新的PoolingHttpClientConnectionManager(socketFactoryRegistry);
                connMgr.setMaxTotal(maxTotalConnections);
                connMgr.setDefaultMaxPerRoute((connMgr.getMaxTotal()));

                HttpClientBuilder构建器= HttpClients.custom()
                        .setDefaultRequestConfig(requestConfig)
                        .setSslcontext(sslContext)
                        .setConnectionManager(connMgr)
                        .setRetryHandler(retryHandler);

                this.httpClient = builder.build();


            }捕获(异常e){
                e.printStackTrace();
            }

        }

        公共HttpClient getHttpClient(){

            返回this.httpClient;
        }

        公共无效destroy(){

            if(this.httpClient!= null){
                尝试{
                    this.httpClient.close();
                    this.httpClient = null;
                }捕获(异常e){
                    e.printStackTrace();
                }

            }
        }


    }

当我使用此类发送帖子请求时。发生了一些奇怪的事情:

第一次,我将发布请求发送到服务器,几分钟后没问题,我将相同的请求发送到服务器,也行。但是几分钟后,我发送了相同的请求,出现了错误:

    java.net.SocketException:连接被对等方重置:套接字写入错误
        在java.net.SocketOutputStream.socketWrite0(本机方法)
        在java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:92)
        在java.net.SocketOutputStream.write(SocketOutputStream.java:136)
        在org.apache.http.impl.conn.LoggingOutputStream.write(LoggingOutputStream.java:77)
        在org.apache.http.impl.io.SessionOutputBufferImpl.streamWrite(SessionOutputBufferImpl.java:126)
        在org.apache.http.impl.io.SessionOutputBufferImpl.flushBuffer(SessionOutputBufferImpl.java:138)
        在org.apache.http.impl.io.SessionOutputBufferImpl.flush(SessionOutputBufferImpl.java:146)
        在org.apache.http.impl.BHttpConnectionBase.doFlush(BHttpConnectionBase.java:175)
        在org.apache.http.impl.DefaultBHttpClientConnection.flush(DefaultBHttpClientConnection.java:185)
        在org.apache.http.impl.conn.CPoolProxy.flush(CPoolProxy.java:177)
        在org.apache.http.protocol.HttpRequestExecutor.doSendRequest(HttpRequestExecutor.java:215)
        在org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:122)
        在org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:271)
        在org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:184)
        在org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:88)
        在org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
        在org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184)
        在org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:71)
        在org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:220)
        在org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:164)
        在org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:139)
        在com.u8.server.sdk.UHttpAgent.post(UHttpAgent.java:259)
        在com.u8.server.sdk.UHttpAgent.post(UHttpAgent.java:147)
        在com.u8.server.sdk.baidu.BaiduSDK.verify(BaiduSDK.java:30)
        在com.u8.server.web.UserAction.getLoginToken(UserAction.java:100)
        在sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)处
        在sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        在sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        在java.lang.reflect.Method.invoke(Method.java:597)

但是之后,我仍然向服务器发送了相同的请求,再次可以。

每当我按照上述步骤尝试时,都会发生相同的事情。

有人可以帮助我吗?非常感谢。


问题答案:

您的客户端的对等方是服务器。因此,“通过对等方重置连接”意味着服务器重置了套接字。重置表示强制关闭。

这可能是由于服务器中的错误所致。如果您还编写了服务器或Servlet(自定义协议就是这种情况),则需要检查服务器的行为以检查其原因。服务器的日志文件可能会提供线索。

如果服务器具有防止行为异常或恶意客户端的保护,则服务器可能已重置套接字,因为它已将您的客户端归类为行为异常。如果实施了客户端协议代码,则可能是由于协议实施中的错误所致。如果您使用第三方代码来处理通信协议,则可能仍会误用它。例如通过发送过大的请求。HTTP服务器通过为报头字段和正文强加最大长度来保护自己免受拒绝服务攻击,并要求客户端以相当快的速率发送数据(长时间不暂停),这种情况并不少见。您的客户可能已经违反了这些保护措施。



 类似资料:
  • 我使用HttpClient4.4发送get和post请求。并且我刚刚创建了一个httpclient的simpile包装器以方便使用: 当我使用这个类发送post请求时。奇怪的事情发生了: 第一次,我向服务器发送一个post请求,一分钟后就可以了,我向服务器发送一个同样的请求,也可以了。但几分钟后,我发出了一个同样的请求,有些不对劲: 但是,我仍然向服务器发送一个相同的请求,它又可以了。 每次我按照

  • 我正在使用apache HttpClient上传固件文件(.bin)。当我上传一个大小为37MB的这样的文件时,我得到一个错误:连接被对等体重置:套接字写入错误。我不知道怎么解决。但当我尝试其他较小大小的文件(如.txt或.bin)时,没有任何错误。

  • 我正在尝试使用套接字实现一个HTTP服务器。如果客户端(例如浏览器)请求目录,服务器将显示可用文件列表。当客户端请求文件时就会出现问题。我得到以下错误: stacktrace显示问题来自方法: 但我想不出有什么问题。你能帮帮我吗? 编辑 谢谢大家的回答。在我读了你的答案后,我明白了问题是插座出现错误的时候。这是我的错误代码: 我的新代码是这样的:

  • 我还尝试提供私有IP和端口4444,运行脚本后,服务器代理立即关闭,并且收到错误java.net.socketException:Connection reset by Peer:socket write error。 > JMeter控制台日志 我做了telnet privateip:4444,并通过了test命令。服务器代理返回yep数据。此设置正在本地框上工作。不在AWS盒子上。 请让我知道

  • 连接错误:写入套接字时出错104。连接由对等重置。 环境: ubuntu: 16.04 python: 3.6 PC总内存: 32G 我已经安装了redis'3.0.6'。 当您尝试插入500000个数据时,它会成功,但当您尝试插入4000万个大数据时,它会失败。 当尝试将Python数据帧插入redis时,由于容量太大而失败。 数据插入成功: 数据插入失败: ConnectionResetErr

  • 我使用的是是一款开源的100%纯驱动程序,适用于。 -我有连接池配置下面 有时,我会遇到以下异常情况:无法从sql server获取连接。我不知道为什么? java.sql.SQLExc0019: I/O错误:连接重置由对等:套接字写入错误net.sourceforge.jtds.jdbc.TdsCore.executeSQL(TdsCore.java:1052)net.sourceforge.j