简体   繁体   English

服务器在TCP / IP超时后接收数据包

[英]Server receiving packets after timeout TCP/IP

I am writing simple Server through TCP/IP for my android app. 我正在为我的Android应用程序通过TCP / IP编写简单的服务器。

I am facing a problem where server only receives messages after the timeout on the app. 我遇到的问题是服务器仅在应用程序超时后才接收消息。

My server side: 我的服务器端:

            System.out.println("Connection accepted");

            DataOutputStream outToClient = new DataOutputStream(connectionSocket.getOutputStream());
            capitalizedSentence = "READY";

            writeToUser(outToClient, "READY".getBytes());

            String response = readFromUser(connectionSocket); 
                // Server hangs on readFromUser();  

            if(response.contains("IL"))
            {
               byte[] bytes = DatatypeConverter.parseHexBinary(foo);
               writeToUser(outToClient, bytes);
            }

App side: 应用程序端:

            if (ack.equals("READY")) {
                ack = "";
                dataOutputStream.writeBytes(command);
                dataOutputStream.flush();

                buf = new byte[556];
                dataInputStream.read(buf);
                                    // app hangs on read() and gets timeout
            }

The problem is that, server receives command only after application gets read timeout. 问题在于,服务器仅在应用程序读取超时后才接收命令。

My current scenario is this: 我当前的情况是这样的:

  1. Connection accepted: Application receives "READY" 接受连接:应用程序收到“ READY”
  2. Application sends commands and tries to read response from server 应用程序发送命令并尝试从服务器读取响应
  3. Server is hanging on readFromUser() and only receives message after the app gets read timeout. 服务器挂在readFromUser()上,仅在应用程序读取超时后才接收消息。

    Any ideas what am I doing wrong ? 有什么想法我做错了吗?

Update: 更新:

The code works if I use readLine, instead of read(buf) ( if I understand clearly server hangs on read(buf) and is in waiting mode as socket is not closed yet even though no more data is beeing sent. ) 如果我使用readLine而不是read(buf)(如果我清楚地知道服务器挂在read(buf)上并且处于等待模式,因为套接字尚未关闭,即使没有更多数据发送,代码也可以工作)。

However such way I have to add "\\n" after each command, and server is only emulator, app works with different device who does not understand "\\n" at the end and will crash. 但是,这样的方式我必须在每个命令后添加“ \\ n”,并且服务器仅是模拟器,应用程序可与其他设备一起工作,这些设备最后都不了解“ \\ n”,并且会崩溃。 Is there any way I could make this work without using readLine() ? 没有使用readLine()有什么办法可以使这项工作吗?

Update 2 更新2

   public void writeToUser(DataOutputStream outToClient, byte[] bytes) throws IOException 
   {
       outToClient.write(bytes);
       outToClient.flush();
       String s = new String(bytes);

       writeLog("Sent to client: " + s);
   }

   public String readFromUser(Socket socket) throws IOException, InterruptedException
   {
        writeLog("Reading...");

        BufferedReader inFromClient = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        String clientSentence = inFromClient.readLine();

        writeLog("Received: " + clientSentence);
        return clientSentence;
   }

Above readFromUser() method works just as expected. 上面的readFromUser()方法按预期工作。 But, this requires adding "\\n" on each command sent from client app. 但是,这需要在从客户端应用发送的每个命令上添加"\\n" And real device I have to communicate with does not understand "\\n" and will treat the command as unrecognized... I am writing this server simply for testing purposes and I want it to be as close to real one as possible. 我必须与之通信的真实设备无法理解"\\n"并且会将命令视为无法识别...我仅出于测试目的而编写此服务器,并且希望它尽可能接近真实的设备。

Previously I was just trying to get it done without "\\n" on each command using inFromClient.read(cbuf); 以前,我只是尝试使用inFromClient.read(cbuf);在每个命令上都没有"\\n"来完成它inFromClient.read(cbuf); instead of readLine() and server always got hung on read, and received command only after socket was closed on client side. 而不是readLine()并且服务器始终挂在读取状态,并且仅在客户端关闭套接字后才接收命令。 Even though I know that client sent the command and is waiting for response. 即使我知道客户端已发送命令并正在等待响应。

The question is how can I receive command without using readLine(); 问题是如何不使用readLine();来接收命令readLine(); and "\\n" on client side. "\\n"在客户端。

'how can I receive command without using readLine(); '如何不使用readLine()来接收命令; and "\\n" on client side'. 和“ \\ n”在客户端”。 If you do not, or can not, want to use "\\n" as a command terminator, then you must use another protocol to identify the start and end of the 'command' within the TCP octet/byte stream. 如果您不想或不希望使用“ \\ n”作为命令终止符,则必须使用另一种协议来标识TCP八位位组/字节流中“命令”的开始和结束。

What protocol does your 'real device' server use to identify the start and end of commands? 您的“真实设备”服务器使用什么协议来标识命令的开始和结束? If it uses a byte-by-byte state-machine to identify a valid command then you are going to have to duplicate that in your test server. 如果它使用逐字节状态机来标识有效命令,那么您将不得不在测试服务器中复制该命令。

You're reading lines but you aren't writing lines. 您正在阅读台词,但您没有在写台词。 So readLine() blocks until a line terminator arrives or the peer closes the connection. 因此,readLine()会阻塞,直到行终止符到达或对等方关闭连接为止。

Append a \\n. 附加\\n.

Why not you increase timeout from APPs side. 为什么不从APP端增加超时时间呢? Or you can write a thread that will hit server in some interval for some time and if no response then show time out. 或者,您可以编写一个线程,该线程将在一定时间间隔内到达服务器一段时间,如果没有响应,则表明超时。 This problem is in Apps side. 这个问题是在应用程序方面。

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

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