java – 为什么android HttpURLConnection没有发回FIN?

java – 为什么android HttpURLConnection没有发回FIN?,第1张

概述从我的 Android应用程序中,我想将数据发布到服务器并获取响应,处理它然后发回并获得另一个请求.由于它是持续通信直到没有更多响应进程,我更喜欢使用http.keepAlive = true的HttpURLConnection. 我尝试重用套接字是成功的,但我遇到的问题是: >我试图从客户端(Android应用程序)启动关闭,因为如果 终止从服务器开始,然后服务器进入 TIME_WAIT状态.我 从我的 Android应用程序中,我想将数据发布到服务器并获取响应,处理它然后发回并获得另一个请求.由于它是持续通信直到没有更多响应进程,我更喜欢使用http.keepAlive = true的httpURLConnection.

我尝试重用套接字是成功的,但我遇到的问题是:

>我试图从客户端(AndroID应用程序)启动关闭,因为如果
终止从服务器开始,然后服务器进入
TIME_WAIT状态.我不希望我的服务器进入该状态,所以我更喜欢我的客户端启动终止.但不幸的是
我发现没有合适的方法来使用httpURLConnection
>经过几个小时的搜索,我放弃了做上述尝试
从基于服务器的启动关闭开始
keepalivetimeout,但是当服务器发送FIN时,客户端仅使用ACK响应,因为该连接保持打开状态
服务器中的FIN_WAIT_2和代理中的CLOSE_WAIT.

源代码:

private httpStatus communicateWithMDMServer(String httpUrl,String dataToSend,boolean keepAlive) {    httpStatus status = new httpStatus(http_STATUS_FAILURE);    try {        initializeConnection(httpUrl,keepAlive);        postDataToConnection(connection,dataToSend);        status = readDataFromConnection(connection);    } catch (MalformedURLException e) {        MDMLogger.error("Failed to send data to server as the URL provIDed is not valID "+ e.getMessage()+"\n");        e.printstacktrace();    } catch (IOException e) {        MDMLogger.error("Failed to send the status to the server : IOException "+ e.getMessage()+"\n"+e.getStackTrace());        e.printstacktrace();        readErrorStreamAndPrint(connection);    }    connection.disconnect();    return status;}/** * API to close connection,calling this will not force the connection to shutdown * this will work based on the Connection header set. * @param connection */public voID closeConnection(){    if(connection != null){        connection.disconnect();    }}/** * Used to initialize the httpURLConnection for the given url * All propertIEs required for connection are preset here  * Connection Time Out : 20 Seconds * Connection Type     : keep alive * Content Type        : application/Json;charset=UTF-8 * And also All certificates will be evaluated as ValID.[ Todo will be removed soon] * @param httpUrl * @return * @throws MalformedURLException * @throws IOException */private voID initializeConnection(String httpUrl,boolean keepAlive) throws MalformedURLException,IOException{    URL url = new URL(httpUrl);    connection = (httpsURLConnection) url.openConnection();    connection.setConnectTimeout(20000);    connection.setReadTimeout(20000);    connection.setDoinput(true);    connection.setDoOutput(true);    connection.setRequestMethod("POST");                                                                        //NO I18N    connection.setRequestProperty("Content-Type","application/Json;charset=UTF-8");                            //NO I18N    connection.setRequestProperty("Connection","Keep-Alive");      //NO I18N}/** * API to post data to given connection  * call to this API will close the @OutputStream * @param connection * @param data * @throws IOException */private voID postDataToConnection(URLConnection connection,String data) throws IOException{    OutputStream outStream = connection.getoutputStream();    BuffereDWriter writer = new BuffereDWriter(new OutputStreamWriter(outStream));    writer.write(data);    writer.flush();    writer.close();    outStream.close();}/** * API to read error stream and log * @param connection */private voID readErrorStreamAndPrint(URLConnection connection){    try{        inputStream inStream = ((httpURLConnection) connection).getErrorStream();        String responseData = "";        String line;        BufferedReader br=new BufferedReader(new inputStreamReader(inStream));        while ((line=br.readline()) != null) {            responseData+=line;        }        MDMLogger.error("ErrorStream Says "+responseData);    } catch (IOException ioe) {        MDMLogger.deBUG("Exception on reading ErrorStream");    }}/** * API to read data from given connection and return {@code com.manageengine.mdm.framework.communication.httpStatus} * call to this API will close the @inputStream * @param connection * @return * @throws IOException */private httpStatus readDataFromConnection(URLConnection connection) throws IOException{    httpStatus status = new httpStatus(http_STATUS_FAILURE);    int responseCode=((httpURLConnection) connection).getResponseCode();    MDMLogger.info("Response Code: "+responseCode);    inputStream inStream = connection.getinputStream();    MDMLogger.info("Response header: "+connection.getheaderFIElds());    String responseData = "";    if (responseCode == httpURLConnection.http_OK) {        responseData = readStreamAsstring(inStream);        status.setStatus(http_STATUS_SUCCESS);        status.setUrlDataBuffer(responseData);        MDMLogger.info("communicateWithMDMServer : Response is \n"  + status.getUrlDataBuffer());        MDMLogger.info("Successfully send the data to server and received success response ");    }    else {        status.setStatus(http_STATUS_FAILURE);        MDMLogger.error("Data sent successfully but Failed to get the response and the response code is : " + responseCode);    }    inStream.close();    return status;}/** * Read the inputStream to String until EOF * Call to this API will not close @inputStream * @param inStream * @return * @throws IOException */private String readStreamAsstring(inputStream inStream) throws IOException{    StringBuilder responseData = new StringBuilder();    String line;    BufferedReader br=new BufferedReader(new inputStreamReader(inStream));    while ((line=br.readline()) != null) {        responseData.append(line);    }    return responseData.toString();}

有人可以帮忙吗?

解决方法 当您使用http.keepAlive = true时,连接开始在连接池中循环使用,并保持打开状态.即使服务器关闭了它仍在监听的连接,客户端仍然认为它可以发送数据.毕竟,服务器的FIN只表示服务器不会发送更多数据.

由于连接池的内部逻辑无法访问,因此您几乎无法控制.然而,当您使用https时,您有一个打开较低层的窗口,可以通过httpsURLConnection.setSSLSocketFactory(SSLSocketFactory)访问创建的Socket.

您可以为默认工厂(SSLSocketFactory.getDefault())创建一个允许关闭Socket的包装器.下面的简化:

public class MySSLSocketFactory extends SSLSocketFactory {    private SSLSocketFactory factory = (SSLSocketFactory) SSLSocketFactory.getDefault();    private Socket last;    public voID closeLastSocket() {        if (last != null) {            last.close();        }    }    public Socket createSocket() throws IOException {        return this.last = factory.createSocket();    }    ...}

当您关闭底层套接字时,该连接不应该有资格进行回收,并将被丢弃.因此,如果您执行closeLastSocket并断开连接,则连接甚至不应该转到池中,如果您执行其他方式,则只有在创建新连接时才会丢弃连接.

总结

以上是内存溢出为你收集整理的java – 为什么android HttpURLConnection没有发回FIN?全部内容,希望文章能够帮你解决java – 为什么android HttpURLConnection没有发回FIN?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1148249.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-31
下一篇 2022-05-31

发表评论

登录后才能评论

评论列表(0条)

保存