Android TCP Client. Server only receives messages

2020-02-14 09:58发布

I have simple TCP server written in Java, and I'm trying to write a simple TCP client for Android that will communicate with the TCP server running on the local machine.

I can get the server to receive messages, but oddly it is only receiving the message AFTER I stop the Application process through the "Devices" window in Eclipse.

On the Android client, I have the main UI thread which contains fields to enter the IP address and Port number(this all works fine so I am not including the code for it). When the connect button is clicked, it starts a new ASyncTask to do the TCP socket work.

Here is the code for the ConnectionTask class's doInBackground method:

    protected Void doInBackground(Void... params) 
    {   
    String authMessage = "Authorize";
    boolean connected=false;
    try 
    {           
        Socket clientSocket = new Socket();
        SocketAddress serverAddress = new InetSocketAddress(address,port);
        Log.v("Connection Thread", serverAddress.toString());
        clientSocket.connect(serverAddress, 15);
        if(clientSocket.isConnected())
        {
            connected = true;
            Log.v("Connection Thread", "Connection Successful");
            DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
            BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
            outToServer.writeBytes(authMessage);
            Log.v("Connection Thread", "Sent Auth Message");
            String response = inFromServer.readLine();

            Log.v("TCP Client", "Response: " + response);
            hash = computeHash(response.getBytes());
            //send the computed hash to the server
            outToServer.writeBytes(hash);
            outToServer.close();
            inFromServer.close();
            clientSocket.close();
        }
        else
        {
            Log.v("Connection Thread", "Not Connected yet...");
        }
    } 
    catch (Exception e) 
    {
        Log.v("Connection Thread", e.getMessage());
    }   
    return null;
}

When I press the connect button, in the emulator I see the logs up to "Sent Auth Message" but my server does not receive the message "Authorize" until I kill the process through DDMS.

Here is the server code:

    public class Server
{
       private static SecureRandom random = new SecureRandom();
       public static void main(String argv[]) throws Exception
       {
             String rawClientMessage,lcClientMessage;
             ServerSocket welcomeSocket = new ServerSocket(5000);
             System.out.println("Starting Server...");
             while(true)
             {
                Socket connectionSocket = welcomeSocket.accept();
                BufferedReader inFromClient = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
                DataOutputStream outToClient = new DataOutputStream(connectionSocket.getOutputStream());
                rawClientMessage = inFromClient.readLine();
                if(rawClientMessage!=null)
                {
                    lcClientMessage = rawClientMessage.toLowerCase() + '\n';
                    System.out.println("Received Message! Contents: " + rawClientMessage);
                    if(lcClientMessage=="authorize")
                    {
                        System.out.println("Received auth request message, generating key...");
                        String key = generateKey();
                        //send key back
                        outToClient.writeBytes(key);
                        System.out.println("Key sent!");
                    }
                }
                try
                {
                    inFromClient.close();
                    outToClient.close();
                    connectionSocket.close();
                }
                catch(Exception e)
                {
                    System.out.println(e.getMessage());
                }
             }
       }

       private static String generateKey()
       {
             return new BigInteger(130, random).toString(32);
       }
}

EDIT:

Here is a step by step summary of what happens:

  1. I start the server (it blocks waiting for connection and reads "Server started...")
  2. I type in 192.168.0.100 port 5000 into android client and hit "connect" button
  3. ASyncTask is created upon click and my socket code is listed above
  4. Nothing is received on server console yet...
  5. (I could press connect again and nothing would happen) (LogCat also reads up to the "Send Auth Message" log)
  6. I kill process on emulator through Eclipse devices window
  7. Server console prints: Received Message! Contents: Authorize (message is displayed twice if I clicked connect twice)

Basically it seems like it's storing the message and is letting them all out onto the wire after the close of the program.

Any help is appreciated, thanks! Can post more code including main UI thread and rest of ConnectionTask class which extends ASyncTask (if needed).

Thanks!

3条回答
成全新的幸福
2楼-- · 2020-02-14 10:05

You have to redirect your port if you run your app in emulator. Otherwise you can't communicate client with server. Take a look

查看更多
干净又极端
3楼-- · 2020-02-14 10:25

You are reading lines but you aren't writing lines. readLine() will block until it receives a line terminator, and you are never sending one. And as the data you are receiving is binary, you shouldn't be trying to read it with readLine() anyway. Reconsider your data streams.

查看更多
Juvenile、少年°
4楼-- · 2020-02-14 10:29

writeBytes(message) writes the bytes to the output stream, but they aren't sent down the pipe until the stream is flushed. When you kill the app, the stream is closed, and before the stream gets closed it flushes itself.

I think if you add outToClient.flush() after the outToClient.writeBytes(authMessage) you'll be rockin'.

查看更多
登录 后发表回答