[英]Android client/server application - proper way to receive messages continously
I'm trying to make a client/server application using an Android phone as a client using AsyncTask
to send messages from UI. 我正在尝试使用Android手机作为使用AsyncTask
从UI发送消息的客户端来制作客户端/服务器应用程序。
I've written some very basic implementation just to test the connection and the way that messages are received / sent and I found a very big problem. 我写了一些非常基本的实现,只是为了测试连接和消息收发的方式,我发现了一个很大的问题。
The client part seems to work fine..from my perspective. 从我的角度来看,客户端部分似乎工作正常。 But the server part is the problem. 但是服务器部分是问题所在。 I can't make the server reading and displaying messages countinously from the client. 我无法使服务器从客户端大量读取和显示消息。
I tried something like while(line = (in.readLine()) != null) {}
but it doesn't seems to work. 我尝试了类似while(line = (in.readLine()) != null) {}
但它似乎不起作用。
After I sent my first word from the client, the server reads null and it stops. 从客户端发送第一个单词后,服务器读取null并停止。
Can someone show me a proper way to keep the server running while the client is not sending nothing? 有人可以向我展示一种在客户端不发送任何内容时保持服务器运行的正确方法吗? I'd like to avoid using while(true)
if it's not 100% necessary. 如果不是100%必要,我想避免使用while(true)
。
Here is the implementation until now: 这是到目前为止的实现:
Server: 服务器:
public class SocketServerThread extends Thread {
private static final Logger log = Logger.getLogger(SocketServerThread.class);
private static final int SERVER_PORT_NUMBER = 5000;
@Override
public void run() {
try {
ServerSocket serverSocket = new ServerSocket(SERVER_PORT_NUMBER);
serverSocket.setReuseAddress(true);
log.info("Waiting for connection...");
Socket clientSocket = serverSocket.accept();
log.info("Connected! Receiving message...");
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
try {
while (true) {
String line = in.readLine();
if (line != null) {
log.info(line);
}
}
} catch (Exception e) {
log.error("Unexpected exception while sending / receiving messages.");
e.printStackTrace();
} finally {
in.close();
clientSocket.close();
serverSocket.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
Client: 客户:
public class MyAsyncTask extends AsyncTask<String, Integer, String> {
private static final String TAG = "MyAsyncTask";
private static final String SERVER_IP_ADDRESS = "10.0.2.2";
private static final int SERVER_PORT_NUMBER = 5000;
private PrintWriter out;
@Override
protected String doInBackground(String... params) {
String message = "";
try {
InetAddress address = InetAddress.getByName(SERVER_IP_ADDRESS);
Log.d(TAG, "Connecting...");
Socket socket = new Socket(address, SERVER_PORT_NUMBER);
try {
out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
Log.d(TAG, "I/O created");
message = params[0];
if (!message.equals("stop")) {
sendMessage(message);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
out.flush();
out.close();
socket.close();
}
} catch (Exception e) {
e.printStackTrace();
}
return message;
}
private void sendMessage(String message) {
if (out != null && !out.checkError()) {
out.println(message);
out.flush();
Log.d(TAG, "Sent message: " + message);
}
}
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
Log.d(TAG, "onPostExecute(), s: " + s);
}
Thank you. 谢谢。
The problem is that your BufferedReader only read the first input stream. 问题在于您的BufferedReader仅读取第一个输入流。 In order to receive the text after that, you have to re-read the input stream. 为了在此之后接收文本,您必须重新阅读输入流。 I do it by recreating the socket when I am done reading, so that I can read next coming data. 我通过在完成读取后重新创建套接字来完成此操作,以便可以读取下一个即将到来的数据。 I am using the following code in my app. 我在我的应用程序中使用以下代码。 You can use this 你可以用这个
private ServerSocket serverSocket;
public static final int SERVERPORT = 5000;
Thread serverThread = null;
public void startSocketServer(){
this.serverThread = new Thread(new ServerThread());
this.serverThread.start();
}
public void stopSocket(){
if(serverSocket != null){
try{
serverSocket.close();
}
catch (IOException e){
e.printStackTrace();
}
}
}
class ServerThread implements Runnable {
public void run() {
Socket socket = null;
try {
Log.wtf(TAG,"Socket: New Socket");
serverSocket = new ServerSocket(SERVERPORT);
if(serverSocket == null){
runOnUiThread(new Runnable() {
@Override
public void run() {
startSocketServer();
}
});
return;
}
while (!Thread.currentThread().isInterrupted() && !serverSocket.isClosed()) {
try {
socket = serverSocket.accept();
Log.wtf(TAG,"Socket: Accepting");
CommunicationThread commThread = new CommunicationThread(socket);
new Thread(commThread).start();
} catch (IOException e) {
Log.wtf(TAG,"Socket: Error");
e.printStackTrace();
}
if(Thread.currentThread().isInterrupted()){
Log.wtf(TAG, "Thread Interrupted");
}
if(serverSocket.isClosed()){
Log.wtf(TAG, "serverSocket closed");
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
class CommunicationThread implements Runnable {
private Socket clientSocket;
public CommunicationThread(Socket clientSocket) {
this.clientSocket = clientSocket;
log.info("Connected! Receiving message...");
try {
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
try {
while (true) {
String line = in.readLine();
if (line != null) {
log.info(line);
}
else
break;//This will exit the loop and refresh the socket for next data
}
} catch (Exception e) {
log.error("Unexpected exception while sending / receiving messages.");
e.printStackTrace();
}
finally {
in.close();
clientSocket.close();
}
refreshSocket();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void refreshSocket(){
runOnUiThread(new Runnable() {
@Override
public void run() {
stopSocket();
startSocketServer();
}
});
}
Just call startSocketServer() to start the server socket in your code. 只需调用startSocketServer()即可在代码中启动服务器套接字。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.