重置Wi-Fi连接后,Android套接字表现异常

时间:2013-09-12 14:02:33

标签: android sockets wifi

我目前正在开展一项研究项目,要求我在Android中执行以下协议:

  1. 使用Wi-Fi建立与任意Web服务器的连接(3次握手)
  2. 断开并重新连接到同一Wi-Fi接入点
  3. 使用Wi-Fi发送HTTP GET请求
  4. 我已经设法使用C(在Linux环境中)和Java(在Windows环境中)执行此协议。但是,当我尝试使用以下代码在Android中执行相同操作时,在断开连接并重新连接到同一Wi-Fi接入点后,我无法发送HTTP GET请求。

    try {
        // executes 3-way handshake
        Socket socket = new Socket(InetAddress.getByName("www.google.com"), 80);
    
        // disconnects/reconnects to WiFiAP
        WifiManager wifiManager = (WifiManager) baseActivity.getSystemService(Context.WIFI_SERVICE);
        wifiManager.disconnect();
        Thread.sleep(3000);
        wifiManager.reconnect();
        Thread.sleep(3000);
    
        // sends HTTP GET request
        PrintWriter pw = new PrintWriter(socket.getOutputStream());
        pw.println("GET / HTTP/1.1");
        pw.println("Host: www.google.com");
        pw.println("");
        pw.flush();
    
        // prints web server response to display
        BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        String t;
        while ((t = br.readLine()) != null) {
            outputResults(t);
        }
        br.close();
    
    } catch (UnknownHostException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    

    Wireshark显示3次握手成功执行。但是,在断开/重新连接到接入点之后,输出流永远不会刷新。 最初,我认为问题可能是由于超时。但是,如果不是断开/重新连接到Wi-Fi接入点而是引入等效的时间延迟,则代码可以正常工作。

    我被困在这一个大约一个星期。任何帮助都非常感谢!

1 个答案:

答案 0 :(得分:1)

欢迎来到Android WiFi插槽地狱。我通常认识到,通过捕获异常并在异常消息中搜索文本“broken pipe”来中断底层连接:

if (socketException.getMessage().toLowerCase().contains("broken pipe")) {
    forceReconnection();
}

所以forceReconnection()清除输入/输出缓冲区:

protected void disposeIO() {

    // shoutdown socket IO
    try {
        socket.shutdownInput();
    } catch (Exception e) {
    }

    try {
        socket.shutdownOutput();
    } catch (Exception e) {
    }

    try {
        this.inputReader.close();
        this.inputReader = null;
    } catch (Exception e) {
    }

    // close out stream
    try {
        outputStream.close();
        outputStream = null;
    } catch (Exception e) {
    }
}

并重新建立与我的端点calling socket.close()的连接并重新创建套接字,输入阅读器,输出流