如何使用套接字从服务器读取数据?
How to use sockets to read data from server?
该应用程序有 MainActivity(包含一个 EditText 和一个 Button)和 DisplayActivity(包含一个 TextView)用户在 EditText 中输入消息并按下发送按钮。来自 EditText 的消息字符串被发送到服务器。然后开始一个新的意图到 DisplayActivity。 DisplayActivity 将使用 readLine() 从服务器读取数据,并根据从服务器接收到的数据设置 TextView。
activity_main.xml 有一个 id="@+id/message_textView" 的 EditText 和一个 id="@+id/send_button" 的 Button。 DisplayActivity 有 android:id="@+id/displayTextView".
我向服务器发送数据的代码可以正常工作,但是当我尝试从服务器读取数据时,readline() 就停在那里并永远坐在那里。
Android 应用有 MainActivity 和 DisplayActivity class。
我运行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());
}
}
}
主要活动
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);
}
}
}
当我 运行 调试器时,它实际上只是在 doInBackground() 方法中的 msgReceived = bufferedReader.readLine() 上的 DisplayActivity.java 停止并且没有给出错误。
我的服务器启动正常,当我将数据从我的应用程序发送到服务器时,在 Eclipse 上它会打印出发送的内容(有时由于某种原因为空)。
----------------解决方案----------------
绿色应用程序回答了问题,但基本上服务器 class 希望在连接首次打开时读取一些内容,然后发送数据。然而在 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;
}
}
}
您有两个客户端套接字。还有两个服务器套接字。
这是一个非常奇怪的方法。
第一个客户端发送一条线并关闭连接。这工作正常,因为服务器尝试读取该行并执行。然后两者都关闭。
然后启动第二个客户端。这个连接到一个新的服务器套接字。但是这个客户端直接尝试读取一行。由于服务器也尝试从这个新客户端读取一行,两者都将在 readLine() 上等待永恒。
该应用程序有 MainActivity(包含一个 EditText 和一个 Button)和 DisplayActivity(包含一个 TextView)用户在 EditText 中输入消息并按下发送按钮。来自 EditText 的消息字符串被发送到服务器。然后开始一个新的意图到 DisplayActivity。 DisplayActivity 将使用 readLine() 从服务器读取数据,并根据从服务器接收到的数据设置 TextView。
activity_main.xml 有一个 id="@+id/message_textView" 的 EditText 和一个 id="@+id/send_button" 的 Button。 DisplayActivity 有 android:id="@+id/displayTextView".
我向服务器发送数据的代码可以正常工作,但是当我尝试从服务器读取数据时,readline() 就停在那里并永远坐在那里。
Android 应用有 MainActivity 和 DisplayActivity class。
我运行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());
}
}
}
主要活动
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);
}
}
}
当我 运行 调试器时,它实际上只是在 doInBackground() 方法中的 msgReceived = bufferedReader.readLine() 上的 DisplayActivity.java 停止并且没有给出错误。
我的服务器启动正常,当我将数据从我的应用程序发送到服务器时,在 Eclipse 上它会打印出发送的内容(有时由于某种原因为空)。
----------------解决方案----------------
绿色应用程序回答了问题,但基本上服务器 class 希望在连接首次打开时读取一些内容,然后发送数据。然而在 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;
}
}
}
您有两个客户端套接字。还有两个服务器套接字。
这是一个非常奇怪的方法。
第一个客户端发送一条线并关闭连接。这工作正常,因为服务器尝试读取该行并执行。然后两者都关闭。
然后启动第二个客户端。这个连接到一个新的服务器套接字。但是这个客户端直接尝试读取一行。由于服务器也尝试从这个新客户端读取一行,两者都将在 readLine() 上等待永恒。