简体   繁体   中英

How to use sockets to read data from server?

The app has MainActivity(contains an EditText and a Button) and DisplayActivity(contains a single TextView)The user enters a message in the EditText and presses the send button. The message string from the EditText gets sent to the server. Then starts a new intent to DisplayActivity. DisplayActivity will read data from the server with readLine(), and set TextView from the data received from the server.

activity_main.xml has a EditText with id="@+id/message_textView" and Button with id="@+id/send_button". DisplayActivity has android:id="@+id/displayTextView".

My code to send data to the server works, but when I try to read data from the server, readline() just stops there and sits there forever.

Android app has MainActivity and DisplayActivity class.

I run the server code in eclipse.

Server code.

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);
        }
    }
}

When i run debugger, it literally just stops in DisplayActivity.java on msgReceived = bufferedReader.readLine() in the doInBackground() method and gives no error.

My server starts fine and when I send data from my app to the server, on eclipse it prints out what was sent(and sometimes null for some reason).

在此处输入图片说明

---------------SOLUTION---------------

Question was answered by green apps, but basically the server class expects to read something when a connection first opens, and then send out data. However in ReadTask, all it does is try to read data from the server(but it should send data first, then read from it)

Updated code.

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;
        }
    }
}

在此处输入图片说明

You have two clientsocketss. And two serversockets.

Which is a very strange approach.

The first client sends a line and closes the connection. This works ok as the server tries to read that line and does. Both then close.

Then you start the second client. This one connects to a new serversocket. But this client directly tries to read a line. As the server also tries to read a line from this new client both will wait for eternity on readLine().

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM