2

我目前正在从事一个研究项目,该项目需要我在 Android 中执行以下协议:

  1. 使用 Wi-Fi 与任意 Web 服务器建立连接(3 次握手)
  2. 断开并重新连接到同一个 Wi-Fi 接入点
  3. 使用 Wi-Fi 发送 HTTP GET 请求

我已经设法使用 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 接入点,而是引入了等效的时间延迟,则代码可以正常工作。

我已经坚持了大约一个星期。非常感谢任何帮助!

4

1 回答 1

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()创建套接字、输入阅读器、输出流

于 2013-09-12T14:10:26.113 回答