简体   繁体   English

通过TCP套接字从Java Server返回消息到Android客户端

[英]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.

相关问题 是否可以使用TCP套接字将JSON数据从Java服务器发送到Android客户端 - Is it possible to send json data from java server to android client using TCP sockets 通过单击按钮将文本消息从 java 服务器发送到 android 客户端使用套接字 - send text message from java server to android client usig sockets by clicking on a button Java套接字:检查客户端是否能够从服务器接收消息 - Java Sockets: check if client is able to receive message from server 有没有办法只在 Java 套接字中从服务器向一个客户端发送消息? - is there a way to send a message from server to one client only in Java sockets? Java sockets - Output stream 通过方法调用从服务器到客户端 - Java sockets - Output stream from server to client via method call Android tcp客户端连接然后从Java服务器断开连接 - Android tcp client connects then disconnect from java server 通过TCP套接字将对象从Java服务器发送到android客户端 - sending objects through TCP socket from java server to android client 通过套接字Java TCP服务器向Android应用发送对象 - Sending objects through sockets java TCP server to android app java/android TCP sockets - 检测服务器是否离线 - java/android TCP sockets - detecting whether the server is offline Java套接字:从服务器到客户端的开放连接 - Java sockets: open connections from server to client
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM