Android套接字连接超时

时间:2015-05-21 15:36:06

标签: android sockets timeout

我的Android应用程序通过socket连接到服务器,socket以node.js编码。当它在前台停留15分钟时,它会丢失与服务器的连接。以下是将sockt连接到服务器的代码

public void connect() {
    this.connectionStatus = CONNECT_STATUS_CONNECTING;
    Log.v(AppConstants.DEBUG_TAG, userId + " : Connecting to Server");
    if (mThread != null && mThread.isAlive()) {
        return;
    }
    mThread = new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                Log.v(AppConstants.DEBUG_TAG, userId + " : Thread Action Started");
                String secret = createSecret();

                int port = (mURI.getPort() != -1) ? mURI.getPort() : (mURI.getScheme().equals("wss") ? 443 : 80);

                String path = TextUtils.isEmpty(mURI.getPath()) ? "/" : mURI.getPath();
                if (!TextUtils.isEmpty(mURI.getQuery())) {
                    path += "?" + mURI.getQuery();
                }
                String originScheme = mURI.getScheme().equals("wss") ? "https" : "http";
                URI origin = new URI(originScheme, "//" + mURI.getHost(), null);

                SocketFactory factory = mURI.getScheme().equals("wss") ? getSSLSocketFactory() : SocketFactory.getDefault();
                mSocket = factory.createSocket(mURI.getHost(), port);
                mSocket.setKeepAlive(true);


                PrintWriter out = new PrintWriter(mSocket.getOutputStream());
                out.print("GET " + path + " HTTP/1.1\r\n");
                out.print("Upgrade: websocket\r\n");
                out.print("Connection: Upgrade\r\n");
                out.print("Host: " + mURI.getHost() + "\r\n");
                out.print("Origin: " + origin.toString() + "\r\n");
                out.print("Sec-WebSocket-Key: " + secret + "\r\n");
                out.print("Sec-WebSocket-Version: 13\r\n");
                if (mExtraHeaders != null) {
                    for (NameValuePair pair : mExtraHeaders) {
                        out.print(String.format("%s: %s\r\n", pair.getName(), pair.getValue()));
                    }
                }
                out.print("\r\n");
                out.flush();

                HybiParser.HappyDataInputStream stream = new HybiParser.HappyDataInputStream(mSocket.getInputStream());

                // Read HTTP response status line.
                StatusLine statusLine = parseStatusLine(readLine(stream));
                if (statusLine == null) {
                    Log.v(AppConstants.DEBUG_TAG, "Received no reply from server.");
                    throw new HttpException("Received no reply from server.");
                } else if (statusLine.getStatusCode() != HttpStatus.SC_SWITCHING_PROTOCOLS) {
                    throw new HttpResponseException(statusLine.getStatusCode(), statusLine.getReasonPhrase());
                }

                // Read HTTP response headers.
                String line;
                boolean validated = false;

                while (!TextUtils.isEmpty(line = readLine(stream))) {
                    Header header = parseHeader(line);
                    if (header.getName().equals("Sec-WebSocket-Accept")) {
                        String expected = createSecretValidation(secret);
                        String actual = header.getValue().trim();

                        if (!expected.equals(actual)) {
                            Log.v(AppConstants.DEBUG_TAG, "Bad Sec-WebSocket-Accept header value.");
                            throw new HttpException("Bad Sec-WebSocket-Accept header value.");
                        }
                        validated = true;
                    }
                }

                if (!validated) {
                    Log.v(AppConstants.DEBUG_TAG, "No Sec-WebSocket-Accept header.");
                    throw new HttpException("No Sec-WebSocket-Accept header.");
                }
                onConnect();
                Log.v(AppConstants.DEBUG_TAG, userId + " : Thread should be connected by now");
                // Now decode websocket frames.
                mParser.start(stream);
            } catch (EOFException ex) {
                Log.d(AppConstants.DEBUG_TAG, "WebSocket EOF!", ex);
                onDisconnect(0, "EOF");
            } catch (SSLException ex) {
                // Connection reset by peer
                Log.d(AppConstants.DEBUG_TAG, "Websocket SSL error!", ex);
                onDisconnect(0, "SSL");
            } catch (Exception ex) {
                onError(ex);
            }
        }
    });
    Log.v(AppConstants.DEBUG_TAG, userId + " : Thread about to be started");
    mThread.start();
}

anu解决这个问题的方法?

2 个答案:

答案 0 :(得分:6)

经过Google搜索后,我找到了解决这个问题的方法。为套接字连接添加超时。

mSocket.setSoTimeout(10000);

如果没有任何响应,10秒钟它将抛出SocketTimeoutException并在此异常的catch中关闭连接(如果存在),然后再次连接。

catch (SocketTimeoutException e){
                if(mSocket.isConnected()){
                    disconnect();
                }
                connect();
            }

答案 1 :(得分:0)

这是一个简单的示例,显示了如何设置timeout on a java socket

sockAdr = new InetSocketAddress(SERVER_HOSTNAME, SERVER_PORT);
socket = new Socket();
timeout = 5000;
socket.connect(sockAdr, timeout);
reader = new BufferedReader(new InputStreamReader(socket.getInputStream());
while ((data = reader.readLine())!=null) 
      log.e(TAG, "received -> " + data);
log.e(TAG, "Socket closed !");