Android 如何使用套接字从服务器读取数据?
该应用程序具有MainActivity(包含一个EditText和一个按钮)和DisplayActivity(包含一个TextView)。用户在EditText中输入消息并按下send按钮。EditText中的消息字符串被发送到服务器。然后开始显示活动的新意图。DisplayActivity将使用readLine()从服务器读取数据,并根据从服务器接收的数据设置TextView activity_main.xml有一个id为=“@+id/message_textView”的EditText和一个id为=“@+id/send_Button”的按钮。DisplayActivity具有android:id=“@+id/displayTextView” 我的代码可以将数据发送到服务器,但当我尝试从服务器读取数据时,readline()就停在那里,永远坐在那里。 Android应用程序具有MainActivity和DisplayActivity类 我在eclipse中运行服务器代码 服务器代码Android 如何使用套接字从服务器读取数据?,android,sockets,android-asynctask,readline,Android,Sockets,Android Asynctask,Readline,该应用程序具有MainActivity(包含一个EditText和一个按钮)和DisplayActivity(包含一个TextView)。用户在EditText中输入消息并按下send按钮。EditText中的消息字符串被发送到服务器。然后开始显示活动的新意图。DisplayActivity将使用readLine()从服务器读取数据,并根据从服务器接收的数据设置TextView activity_main.xml有一个id为=“@+id/message_textView”的EditText和一个
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.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);
}
});
}
}
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;
}
}
}
公共类DisplayActivity扩展了AppCompative活动{
专用插座;
私人印刷作家;
私有BufferedReader BufferedReader;
私有文本视图显示电视;
私有字符串msgReceived=null;
字符串hostIP=“10.0.2.2”;
int端口=4442;
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_显示);
displayTV=findviewbyd(R.id.displayTextView);
ReadTask ReadTask=新建ReadTask();
readTask.execute();
}
类ReadTask扩展了AsyncTask
{
@凌驾
受保护的字符串背景(字符串…字符串){
字符串结果=”;
尝试
{
//创建一个新套接字并尝试先向其写入,然后再从中读取
插座=新插座(主机IP,端口);
//向服务器添加数据
printWriter=新的printWriter(socket.getOutputStream(),true);
printWriter.println(MainActivity.message);
//获取一个流,以便能够从服务器读取数据
bufferedReader=新的bufferedReader(新的InputStreamReader(socket.getInputStream());
msgReceived=bufferedReader.readLine();
displayTV.setText(msgReceived);
//关闭插座连接
printWriter.close();
bufferedReader.close();
socket.close();
}捕获(IOE异常)
{
e、 printStackTrace();
}
返回结果;
}
}
}
您有两个客户sockets。和两个服务器插座 这是一种非常奇怪的方法 第一个客户端发送一条线路并关闭连接。当服务器尝试读取该行并执行该操作时,该操作正常。然后两者都关闭
然后启动第二个客户端。这个连接到一个新的serversocket。但是这个客户端直接尝试读取一行。由于服务器还试图从这个新客户端读取一行数据,这两个客户端都将在readLine()上等待永恒。您有两个clientsockets。还有两个服务器套接字 这是一种非常奇怪的方法 第一个客户端发送一条线路并关闭连接。当服务器尝试读取该行并执行该操作时,该操作正常。然后两者都关闭
然后启动第二个客户端。这个连接到一个新的serversocket。但是这个客户端直接尝试读取一行。由于服务器还试图从这个新客户端读取一行数据,这两个客户端都将在readLine()上等待永恒。它应该停止,直到数据到达出于某种原因,您已经到达了流的末尾,正如Javadoc中所述,在套接字的情况下,这意味着对等方关闭了连接,这意味着您必须执行同样的操作。OP,很抱歉在这个线程中发布,因为您的问题已经解决,但我无法重现您收到的“null”消息@EJP也很抱歉占用您的时间,您能解释一下控制台中的“null”吗?控制台中出现的唯一情况是,if
message
此行中的变量printWriter.println(message)代码>为空。它似乎与套接字打开/关闭问题无关。另一方面,消息来自“EditText”的getText()
方法,该方法从不返回null,它应该在数据到达之前停止出于某种原因,您已经到达了流的末尾,正如Javadoc中所述,在套接字的情况下,这意味着对等方关闭了连接,这意味着您必须执行同样的操作。OP,很抱歉在这个线程中发布,因为您的问题已经解决,但我无法重现您收到的“null”消息@EJP也很抱歉占用您的时间,您能解释一下控制台中的“null”吗?控制台中出现的唯一情况是,ifmessage
此行中的变量printWriter.println(message)代码>为空。它似乎与套接字打开/关闭问题无关。另一方面,消息来自“EditText”的getText()
方法,该方法从不返回null。在你告诉我出了什么问题后,我修复了它。在MainActivity.java中,我删除了异步任务。在DisplayActivity.java中,我向ReadTask添加了更多代码(用于写入服务器)。服务器中也不再出现null。做得好。如果你只是问…,我会这样建议你的谢谢,我想问题是我不理解套接字是如何工作的。我想我可以打开一个套接字,从服务器读取数据,就像读取数据库一样。另外,请检查更新后的答案,我的解决方案是正确的/有意义的?你通过发布那张照片让我开心了一天。谢谢。你也帮了我很多忙!我被困在这上面有一段时间了。谢谢嘿,在你告诉我出了什么问题后,我把它修好了。在MainActivity.java中,我删除了异步任务。在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;
}
}
}