Как использовать сокеты для чтения данных с сервера? - PullRequest
0 голосов
/ 10 июня 2018

Приложение имеет MainActivity (содержит EditText и кнопку) и DisplayActivity (содержит один TextView). Пользователь вводит сообщение в EditText и нажимает кнопку отправки.Строка сообщения из EditText отправляется на сервер.Затем начинается новое намерение DisplayActivity.DisplayActivity будет считывать данные с сервера с помощью readLine () и устанавливать TextView из данных, полученных с сервера.

activity_main.xml имеет EditText с id = "@ + id / message_textView" и Button с id = "@ + id / send_button".У DisplayActivity есть android: id = "@ + id / displayTextView".

Мой код для отправки данных на сервер работает, но когда я пытаюсь прочитать данные с сервера, readline () просто останавливается на этоми сидит там навсегда.

Android-приложение имеет классы MainActivity и DisplayActivity.

Я запускаю код сервера в Eclipse.

Код сервера.

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
import java.net.*;
import java.io.*;

public class MyServer {

     public static void main(String[] args) throws IOException {

         int portNumber = 4442;

         System.out.println("Starting server..");

         try {
             while(true) {
             ServerSocket serverSocket =
                 new ServerSocket(portNumber);
             Socket clientSocket = serverSocket.accept();     
             PrintWriter out =
                 new PrintWriter(clientSocket.getOutputStream(), true);                   
             BufferedReader in = new BufferedReader(
                 new InputStreamReader(clientSocket.getInputStream()));
             String message = in.readLine();
             System.out.println(message);//Just print to console, to test if server got message
             out.println(message);
             serverSocket.close();
             clientSocket.close();
//           out.close();
//           in.close();
             }
         } catch (IOException e) {
             System.out.println("Exception caught when trying to listen on port "
                 + portNumber + " or listening for a connection");
             System.out.println(e.getMessage());
         }
     }
}

MainActivity

import android.content.Intent;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;

public class MainActivity extends AppCompatActivity {

    static Socket client;
    private PrintWriter printWriter;
    private EditText messageET;
    private Button sendButton;
    private String message;

    static String hostIP = "10.0.2.2";
    static int port = 4442;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        messageET = findViewById(R.id.message_textView);
        sendButton = findViewById(R.id.send_button);

        sendButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                message = messageET.getText().toString();
                messageET.setText("");

                MyTask myTask = new MyTask();
                myTask.execute();

                Intent intent = new Intent(getApplicationContext(), DisplayActivity.class);
                startActivity(intent);
            }
        });
    }

    class MyTask extends AsyncTask<String,Void,String>
    {
        @Override
        protected String doInBackground(String... strings) {
            try
            {
                client = new Socket(hostIP, port);
                printWriter = new PrintWriter(client.getOutputStream(), true);
                //printWriter.write(message);
                printWriter.println(message);
                //printWriter.flush();
                printWriter.close();
                client.close();
            }catch(IOException e)
            {
                e.printStackTrace();
            }
            return null;
        }
    }
}

DisplayActivity

import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;


public class DisplayActivity extends AppCompatActivity {

    //final String TAG = "displayactivitylog";
    private Socket socket;
    private BufferedReader bufferedReader;

    private TextView displayTV;
    private String msgReceived = null;

    String hostIP = "10.0.2.2";
    int port = 4442;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_display);

        displayTV = findViewById(R.id.displayTextView);
        ReadTask readTask = new ReadTask();
        readTask.execute();
    }
    class ReadTask extends AsyncTask<String,Void,String>
    {
        @Override
        protected String doInBackground(String... strings) {
            String result = "";
            try
            {
                //create a new socket and attempt to read from it
                socket = new Socket(hostIP,port);
                bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                //*****the app stops on this line, and nothing happens after*****  
                msgReceived = bufferedReader.readLine();
                //************************************ 
//                while((msgReceived = bufferedReader.readLine()) != null){
//                    result += msgReceived;
//                }

                bufferedReader.close();
                socket.close();
            }catch(IOException e)
            {
                e.printStackTrace();
            }
            return result;
        }
        //update the TextView with the message from the server
        @Override
        protected void onPostExecute(String s) {
            displayTV.setText(s);
            super.onPostExecute(s);
        }
    }
}

Когда я запускаю отладчик, он буквально просто останавливается в DisplayActivity.java на msgReceived = bufferedReader.readLine ()в методе doInBackground () и не дает ошибок.

Мой сервер запускается нормально, и когда я отправляю данные из моего приложения на сервер, при затмении он выводит на печать то, что было отправлено (и иногда по некоторым причинам равно нулю).

enter image description here

--------------- РЕШЕНИЕ ---------------

На вопрос ответили зеленые приложения, но в основном серверный класс ожидает что-то прочитать при первом открытии соединения, а затем отправить данные.Однако в ReadTask все, что он делает, это пытается прочитать данные с сервера (но сначала он должен отправить данные, а затем прочитать с него)

Обновленный код.

MainActivity.java

public class MainActivity extends AppCompatActivity {

    private EditText messageET;
    private Button sendButton;
    static String message;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        messageET = findViewById(R.id.message_textView);
        sendButton = findViewById(R.id.send_button);

        sendButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                message = messageET.getText().toString();
                messageET.setText("");

                Intent intent = new Intent(getApplicationContext(), DisplayActivity.class);
                startActivity(intent);
            }
        });
    }
}

DisplayActivity.java

public class DisplayActivity extends AppCompatActivity {

    private Socket socket;
    private PrintWriter printWriter;
    private BufferedReader bufferedReader;

    private TextView displayTV;
    private String msgReceived = null;

    String hostIP = "10.0.2.2";
    int port = 4442;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_display);

        displayTV = findViewById(R.id.displayTextView);
        ReadTask readTask = new ReadTask();
        readTask.execute();
    }
    class ReadTask extends AsyncTask<String,Void,String>
    {
        @Override
        protected String doInBackground(String... strings) {
            String result = "";
            try
            {
                //create a new socket and attempt to write to it first then read from it
                socket = new Socket(hostIP,port);
                //add data to the server
                printWriter = new PrintWriter(socket.getOutputStream(), true);
                printWriter.println(MainActivity.message);
                //get a stream, to be able to read data from the server
                bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));

                msgReceived = bufferedReader.readLine();
                displayTV.setText(msgReceived);
                //close the socket connections
                printWriter.close();
                bufferedReader.close();
                socket.close();
            }catch(IOException e)
            {
                e.printStackTrace();
            }
            return result;
        }
    }
}

enter image description here

1 Ответ

0 голосов
/ 10 июня 2018

У вас есть два клиента.И два серверных сокета.

Это очень странный подход.

Первый клиент отправляет строку и закрывает соединение.Это работает нормально, так как сервер пытается прочитать эту строку и делает.Затем оба закрываются.

Затем вы запускаете второй клиент.Этот подключается к новому сокету сервера.Но этот клиент напрямую пытается прочитать строку.Поскольку сервер также пытается прочитать строку из этого нового клиента, оба будут ждать вечности в readLine ().

...