简体   繁体   English

Android TCP套接字超时

[英]Android TCP Sockets timeout

I'm doing an app which needs to communicate with TCP sockets.我正在做一个需要与 TCP 套接字通信的应用程序。 I set up a Service which is my TCP Server and an activity which is my TCP Client.我设置了一个作为我的 TCP 服务器的服务和一个作为我的 TCP 客户端的活动。

I have a big delay from sending a message and receiving an answer from the server, like 10 or more seconds.我在发送消息和从服务器接收答复之间有很大的延迟,比如 10 秒或更长时间。 After some days of researches, I found how to set timeout on the client request and all start to work fine.经过几天的研究,我发现了如何根据客户端请求设置超时,并且一切正常。

So my question is, is it mandatory to set up timeout for a TCP connection, otherwise it doesn't work or something else is wrong with my implementation?所以我的问题是,是否必须为 TCP 连接设置超时,否则它不起作用或我的实现有其他问题?

Here's my Client code:这是我的客户代码:

public static void sendTCP(final InetAddress senderAddr, final String Msg, final int serverPort) {
        Thread tclient = new Thread(){
            public void run() {
                boolean connected;
                Socket socket = new Socket();
                try {
                    Log.d("TCP", "Client: Connecting...");
                    socket.bind(null);
                    socket.connect((new InetSocketAddress(senderAddr, serverPort)), 1000);
                    connected = true;
                try {
                    Log.d("TCP", "Client: Sending command.");
                    PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
                    out.println(Msg);
                    out.close();
                } 
                catch (Exception e) {
                    Log.e("TCP", "Client: Error sending.", e);
                }
                } catch (Exception e) {
                    Log.e("TCP", "Client: Error connecting.", e);
                    connected = false;
                }
                finally {
                    if (socket != null) {
                        if (socket.isConnected()) {
                            try {
                                socket.close();
                                Log.d("TCP", "Client: Connection Closed.");
                            } catch (IOException e) {
                                Log.e("TCP", "Client: Error closing connection.", e);
                            }
                        }
                    }
                }
            }
        };
        tclient.start();
    }

And Server's:和服务器的:

public void onStart(Intent intent, int startid) {

    t = new Thread(){
         public void run() {
             try {
                Boolean end = false;
                Log.d("TCP", "Server: Creating server.");
                ServerSocket ss = new ServerSocket(TCPPORT);
                while(!end) {
                    //Server is waiting for client here, if needed
                    Log.d("TCP", "Server: Waiting on packet!");
                    Socket s = ss.accept();
                    BufferedReader input = new BufferedReader(new InputStreamReader(s.getInputStream()));
                    String st = input.readLine();
                    Log.d("TCP", "Server: Message received from client: "+st);

                    InetAddress senderAddr = s.getInetAddress();
                    senderAddrString= senderAddr.getHostAddress();

                    myAddrString = GetLocalIpAddress();
                    myAddr = InetAddress.getByName(myAddrString);

                    if (senderAddr.equals(myAddr)) {
                    }
                    else {
                        //Estraggo dal pacchetto ricevuto
                        try {
                            StringTokenizer tokens = new StringTokenizer(st, "|");
                            flag = tokens.nextToken();
                            userid = tokens.nextToken();
                            payload = tokens.nextToken();
                        }
                        catch (Exception e) {
                            Log.e("TCP", "Server: Errore estrazione dati.");
                        }

                        if (flag.equals(Constants.flag_scan_answer)) {
                            Log.d("TCP", "Server: Flag answer");
                            //devo passare i dati ad un database ScanActivity

                            //database(senderAddrString,userid);

                            System.out.println("RISPOSTA RICEVUTA DAL SERVICE TCP");
                            System.out.println("FLAG " + flag);
                            System.out.println("USERID " + userid);
                            System.out.println("PAYLOAD " + payload);

                            announceReceivingPacket();
                        }

                        else {
                            Log.d("TCP", "Server: CASO NON PREVISTO");
                        }
                    }
                    s.close();
                }
            }
            catch (UnknownHostException e) {
                    e.printStackTrace();
            } 
            catch (IOException e) {
                    e.printStackTrace();
            }
         }
    };
    t.start();
 }

it's mandatory to set up timeout for a TCP connection必须为 TCP 连接设置超时

It isn't mandatory but it's a very good idea.这不是强制性的,但这是一个非常好的主意。 Start by setting it to double or triple the expected service time and adjust so you don't get false positives.首先将其设置为预期服务时间的两倍或三倍,然后进行调整,以免出现误报。 The default read timeout is infinity, and I have seen entire platforms fail in a way that wasn't detectable by the reader in any other way than a read timeout.默认的读取超时是无限的,而且我已经看到整个平台以读取器无法通过读取超时以外的任何其他方式检测到的方式发生故障。

See here for relevant quotations.请参阅此处以获取相关报价。

The connect call连接呼叫

socket.connect((new InetSocketAddress(senderAddr, serverPort)), 1000); socket.connect((new InetSocketAddress(senderAddr, serverPort)), 1000);

can be BeginConnect with a callback that automatically reports failures and timeouts as well as successful connections.可以是带有自动报告失败和超时以及成功连接的回调的 BeginConnect。 At this point you can use BeginSend and BeginReceive on the socket.此时您可以在套接字上使用 BeginSend 和 BeginReceive。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM