我有简单的用Java编写的TCP服务器,我正在尝试为Android编写一个简单的TCP客户端,它将与本地计算机上运行的TCP服务器进行通信。
我可以让服务器接收消息,但奇怪的是它只是在我通过Eclipse中的“Devices”窗口停止应用程序进程后才收到消息。
在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;
}
当我按下连接按钮时,在模拟器中我看到日志最多为“已发送身份验证消息”但我的服务器在通过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);
}
}
编辑:
以下是对所发生情况的逐步总结:
基本上它似乎存储了消息,并且在程序结束后让它们全部出现在线路上。
感谢任何帮助,谢谢!可以发布更多代码,包括主UI线程和扩展ASyncTask的ConnectionTask类的其余部分(如果需要)。
谢谢!
答案 0 :(得分:3)
你正在读行,但你不是在写行。 readLine()
将阻塞,直到收到行终止符,并且您永远不会发送一个。并且由于您收到的数据是二进制的,因此无论如何都不应该尝试使用readLine()
来读取它。重新考虑您的数据流。
答案 1 :(得分:2)
writeBytes(message)
将字节写入输出流,但在刷新流之前不会将它们发送到管道。当您终止应用程序时,流将关闭,在流关闭之前,它会自行刷新。
我认为如果你在outToClient.flush()
之后添加outToClient.writeBytes(authMessage)
,你就会摇滚。
答案 2 :(得分:1)
如果您在模拟器中运行应用,则必须重定向您的端口。否则您无法与服务器通信客户端。 Take a look