Android TCP客户端。 服务器仅在进程停止后接收消息

我有简单的用Java编写的TCP服务器,我正在尝试为Android编写一个简单的TCP客户端,它将与本地机器上运行的TCP服务器通信。

我可以让服务器接收消息,但奇怪的是它只是在我通过Eclipse中的“设备”窗口停止应用程序进程后才收到消息。

在Android客户端上,我有主UI线程,其中包含输入IP地址和端口号的字段(这一切都正常,所以我不包括它的代码)。 单击连接按钮时,它会启动一个新的ASyncTask来执行TCP套接字工作。

这是ConnectionTask类的doInBackground方法的代码:

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; } 

当我按下连接按钮时,在模拟器中我看到日志最多为“已发送validation消息”但我的服务器在我通过DDMS终止进程之前没有收到消息“授权”。

这是服务器代码:

  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); } } 

编辑:

以下是对所发生情况的逐步总结:

  1. 我启动服务器(它阻止等待连接并读取“服务器启动…”)
  2. 我输入192.168.0.100端口5000进入android客户端并点击“连接”按钮
  3. 单击时创建ASyncTask,上面列出了我的套接字代码
  4. 服务器控制台上还没有收到任何内容……
  5. (我可以再次按连接,不会发生任何事情)(LogCat也会读取“发送validation消息”日志)
  6. 我通过Eclipse设备窗口杀死模拟器上的进程
  7. 服务器控制台打印:收到消息! 内容:授权(如果我点击连接两次,则显示两次消息)

基本上它似乎存储了消息,并且在程序结束后让它们全部出现在线路上。

任何帮助表示赞赏,谢谢! 可以发布更多代码,包括主UI线程和其他扩展ASyncTask的ConnectionTask类(如果需要)。

谢谢!

你正在读行,但你不是在写行。 readLine()将阻塞,直到它收到一个行终止符,你永远不会发送一个。 由于您收到的数据是二进制的,因此您不应该尝试使用readLine()来读取它。 重新考虑您的数据流。

writeBytes(message)将字节写入输出流,但在刷新流之前不会将它们发送到管道。 当您终止应用程序时,流将关闭,在流关闭之前,它会自行刷新。

我想如果你在outToClient.flush()之后添加outToClient.flush() ,你就会摇滚。

如果在模拟器中运行应用程序,则必须重定向端口。 否则您无法与服务器通信客户端。 看一看