[英]Return message to Android client from java Server via tcp sockets
I am trying to make a very simple client/server connection. 我正在尝试建立一个非常简单的客户端/服务器连接。 I have Android app as a client and trying to 我将Android应用作为客户端,并试图
1) pass message to Java program on PC and then 1)将消息传递到PC上的Java程序,然后
2) return a message back to the android client. 2)返回一条消息给android客户端。
First part is working fine. 第一部分工作正常。 The problem is in returning the message from server to client. 问题是从服务器向客户端返回消息。
Server code (Java): 服务器代码(Java):
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class Main {
private final static Integer IN_PORT = 4444;
private static ServerSocket serverSocket = null;
private static Socket sktIn;
private static InputStreamReader inputStreamReader;
private static BufferedReader bufferedReader;
private static String message;
private static PrintWriter printWriter;
public static void main(String[] args) {
try {
serverSocket = new ServerSocket(IN_PORT); //Server socket
System.out.println("Server started. Listening to the port " + IN_PORT);
} catch (IOException e) {
System.out.println("Could not listen on port: " + IN_PORT);
}
while (true) {
try {
sktIn = serverSocket.accept(); //accept the client connection
inputStreamReader = new InputStreamReader(sktIn.getInputStream());
bufferedReader = new BufferedReader(inputStreamReader); //get the client message
message = bufferedReader.readLine();
printWriter = new PrintWriter(sktIn.getOutputStream(), true);
printWriter.write("Returned back \n"); //write the message to output stream
printWriter.flush();
printWriter.close();
inputStreamReader.close();
sktIn.close();
System.out.println(message);
} catch (IOException ex) {
System.out.println("Problem in message reading/sending.");
ex.printStackTrace();
}
}
}
}
Client main activity (Android): 客户端主要活动(Android):
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
public class SimpleClientActivity extends Activity {
private final Integer OUT_PORT = 4444;
private final String S_IP = "192.168.1.104";
private EditText textField;
private Button button;
private String message;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
textField = (EditText) findViewById(R.id.editText1); //reference to the text field
button = (Button) findViewById(R.id.button1); //reference to the send button
//Button press event listener
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
message = textField.getText().toString(); //get the text message on the text field
textField.setText(""); //Reset the text field to blank
new ConnectClient(message, S_IP, OUT_PORT, getApplicationContext()).execute();
}
});
}
}
Separate AsyncTask class for connection: 用于连接的单独的AsyncTask类:
import android.content.Context;
import android.os.AsyncTask;
import android.widget.Toast;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
public class ConnectClient extends AsyncTask<String, Void, String> {
private Socket socket;
private PrintWriter printWriter;
private String param;
private Context context;
private Integer PORT;
private String IP;
private static InputStreamReader inputStreamReader;
private static BufferedReader bufferedReader;
private static String message;
public ConnectClient(String par, String ip, Integer prt, Context ctx){
super();
this.context = ctx;
this.param = par;
this.PORT = prt;
this.IP = ip;
}
@Override
public void onPreExecute() {
Toast.makeText(context, "start " + param, Toast.LENGTH_SHORT)
.show();
}
@Override
protected String doInBackground(String... params) {
try {
socket = new Socket(IP, PORT); //connect to server
printWriter = new PrintWriter(socket.getOutputStream(), true);
printWriter.write(param); //write the message to output stream
printWriter.flush();
printWriter.close();
socket = new Socket(IP, PORT); // second connection to server
inputStreamReader = new InputStreamReader(socket.getInputStream());
message = "after isr";
bufferedReader = new BufferedReader(inputStreamReader); //get the client message
message = bufferedReader.readLine();
inputStreamReader.close();
socket.close(); //closing the connection
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return message;
}
@Override
protected void onPostExecute(String result) {
Toast.makeText(context, result, Toast.LENGTH_SHORT).show()
}
@Override
protected void onProgressUpdate(Void... values) {
Toast.makeText(context, "In progress", Toast.LENGTH_SHORT).show();
}
}
The java program executes ok and the Android app runs without any problems but the end result is not as desired. Java程序执行正常,Android应用程序正常运行,但最终结果不理想。
If I remove the second socket = new Socket(IP, PORT); // second connection to server
如果我删除第二个socket = new Socket(IP, PORT); // second connection to server
socket = new Socket(IP, PORT); // second connection to server
, then server is receiving messages fine. socket = new Socket(IP, PORT); // second connection to server
,则server可以正常接收消息。 In the java console I get printed whatever I put in the app and send. 在Java控制台中,我可以打印出我放入应用程序中的所有内容并发送。 But the second Toast is empty (the message from the server is not passed). 但是第二个Toast为空(未传递来自服务器的消息)。 And I get SocketException (closed) in the LogCat: 我在LogCat中得到SocketException(关闭):
01-29 06:38:36.039: W/System.err(11547): java.net.SocketException: Socket is closed
01-29 06:38:36.059: W/System.err(11547): at java.net.PlainSocketImpl.checkNotClosed(PlainSocketImpl.java:134)
01-29 06:38:36.059: W/System.err(11547): at java.net.PlainSocketImpl.getInputStream(PlainSocketImpl.java:216)
01-29 06:38:36.059: W/System.err(11547): at java.net.Socket.getInputStream(Socket.java:343)
01-29 06:38:36.059: W/System.err(11547): at com.example.simpleclient.ConnectClient.doInBackground(ConnectClient.java:63)
01-29 06:38:36.059: W/System.err(11547): at com.example.simpleclient.ConnectClient.doInBackground(ConnectClient.java:1)
01-29 06:38:36.059: W/System.err(11547): at android.os.AsyncTask$2.call(AsyncTask.java:287)
01-29 06:38:36.059: W/System.err(11547): at java.util.concurrent.FutureTask.run(FutureTask.java:234)
01-29 06:38:36.059: W/System.err(11547): at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
01-29 06:38:36.059: W/System.err(11547): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
01-29 06:38:36.059: W/System.err(11547): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
01-29 06:38:36.059: W/System.err(11547): at java.lang.Thread.run(Thread.java:841)
If I leave socket = new Socket(IP, PORT); // second connection to server
如果我离开socket = new Socket(IP, PORT); // second connection to server
socket = new Socket(IP, PORT); // second connection to server
line of code in, there are no error messages, but the message is passed only once to the server. socket = new Socket(IP, PORT); // second connection to server
的代码行,没有错误消息,但是该消息仅传递到服务器一次。 2nd, 3rd, end so forth don't go through (nothing displaying in the console). 第二,第三,第三步等都不会通过(控制台中什么都没有显示)。 Though if I leave the console running and shut down the app, another null comes through. 尽管如果我让控制台运行并关闭应用程序,则会出现另一个null。
In any case, the second Toast (on the client side) is either empty (the message from the server is not passed) or not displayed at all ( message = bufferedReader.readLine();
blocks further execution). 无论如何,第二个Toast(在客户端上)为空(不传递来自服务器的消息)或根本不显示( message = bufferedReader.readLine();
阻止进一步执行)。 For instance, If I comment out the line message = bufferedReader.readLine();
例如,如果我注释掉该行message = bufferedReader.readLine();
, then I get "after isr" in the second Toast. ,然后在第二个Toast中得到“ after isr”。 Or, in the case when the second socket = new Socket(IP, PORT); // second connection
或者,如果第二个socket = new Socket(IP, PORT); // second connection
socket = new Socket(IP, PORT); // second connection
is present the second Toast does not display at all. socket = new Socket(IP, PORT); // second connection
存在第二socket = new Socket(IP, PORT); // second connection
,第二个Toast根本不显示。
What am I missing. 我想念什么。 How do I send a message from server back to the client? 如何将邮件从服务器发送回客户端?
The instructions of client and server must be symmetric. 客户端和服务器的指令必须对称。
If the client writes, the server must read and viceversa 如果客户端写入,则服务器必须读取,反之亦然
If the client opens an inputStream, the server must open an outputStream. 如果客户端打开inputStream,则服务器必须打开outputStream。
Now in the first connection you open only the outputStream but in the server you have both of them. 现在,在第一个连接中,仅打开outputStream,但在服务器中同时拥有它们。
Also you open two connections (client) that are handled as one in the server, so the first printing operations work fine because there are reading operations on server, but the others can't work because you create another connection that the server can't handle because: 另外,您还要打开两个在服务器中作为一个连接处理的连接(客户端),因此第一个打印操作可以正常工作,因为服务器上有读取操作,但是其他打印操作却不起作用,因为您创建了另一个服务器无法连接的连接处理,因为:
1)the server is not multithread 1)服务器不是多线程的
2)the server have to work on the first connection 2)服务器必须在第一个连接上工作
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.