[英]Android java client program using separate thread for socket IO, Can't find a way to send data with a button
Alright first off, I'm fairly new to java and android coding. 首先,我对Java和android编码还很陌生。 I am creating a client program that uses import java.net.Socket to make a connection to a server. 我正在创建一个使用导入java.net.Socket来建立与服务器的连接的客户端程序。 It does so after pressing a "login" button. 按下“登录”按钮后,将执行此操作。 The login button code starts with Thread background = new Thread(new Runnable() {
to start a new thread, then proceeds to make the connection. socket = new Socket(dstAddress, dstPort);
All is well. My problem is that on my interface I also have another button and an EditText with the intent that the user can type commands into the EditText and then press the "Send" button in order to send them to the server. The code for the "Send" button is obviously outside of the code for the "Login" button and therefore outside of that background thread etc. How can I make this work? 登录按钮代码以Thread background = new Thread(new Runnable() {
开头以开始一个新线程,然后继续建立连接socket = new Socket(dstAddress, dstPort);
一切都很好。我的问题是我的界面上我还有另一个按钮和一个EditText,目的是用户可以在EditText中键入命令,然后按“发送”按钮以将其发送到服务器。“发送”按钮的代码显然不在“登录”按钮的代码,因此不在该后台线程等范围之内。如何使这项工作有效?
OutputStream out = socket.getOutputStream();
PrintWriter output = new PrintWriter(out);
output.print(LoginPacket); //send packet to server
output.flush();
is the code I used inside of the "Login" button to send the first packet to the server, but I can't use this code in the "Send" button, gives the error "socket cannot be resolved" 是我在“登录”按钮内部用于将第一个数据包发送到服务器的代码,但是我无法在“发送”按钮中使用此代码,出现错误“无法解决套接字”
Is there a way to make socket globally accessable while it's connected and receiving data from the server such that I can use another button to send data back to the server? 有没有一种方法可以使套接字在连接期间从服务器全局访问,并从服务器接收数据,以便可以使用另一个按钮将数据发送回服务器?
You don't write the socket in the button's click handler. 您无需在按钮的单击处理程序中编写套接字。 Instead, you make the click handler send a message to the socket thread (for example, by adding an item to a synchronized list that the thread is waiting for an object to be places in). 而是使单击处理程序将消息发送到套接字线程(例如,通过将项目添加到线程正在等待放置对象的同步列表中)。 The socket thread then would write the data to the socket. 然后,套接字线程将数据写入套接字。
Here is the code its working for me. 这是它对我有用的代码。
Android Side: Android Side:
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import android.util.Log;
public class TCPClient {
private String serverMessage;
public static final String SERVERIP = "Your IP Address"; //your computer IP address
public static final int SERVERPORT = 4444;
private OnMessageReceived mMessageListener = null;
private boolean mRun = false;
PrintWriter out;
BufferedReader in;
/**
* Constructor of the class. OnMessagedReceived listens for the messages received from server
*/
public TCPClient(OnMessageReceived listener) {
mMessageListener = listener;
}
/**
* Sends the message entered by client to the server
* @param message text entered by client
*/
public void sendMessage(String message){
if (out != null && !out.checkError()) {
out.println(message);
out.flush();
}
}
public void stopClient(){
mRun = false;
}
public void run() {
mRun = true;
try {
//here you must put your computer's IP address.
InetAddress serverAddr = InetAddress.getByName(SERVERIP);
Log.e("TCP Client", "C: Connecting...");
//create a socket to make the connection with the server
Socket socket = new Socket(serverAddr, SERVERPORT);
try {
//send the message to the server
out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
Log.e("TCP Client", "C: Sent.");
Log.e("TCP Client", "C: Done.");
//receive the message which the server sends back
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//in this while the client listens for the messages sent by the server
while (mRun) {
serverMessage = in.readLine();
if (serverMessage != null && mMessageListener != null) {
//call the method messageReceived from MyActivity class
mMessageListener.messageReceived(serverMessage);
}
serverMessage = null;
}
Log.e("RESPONSE FROM SERVER", "S: Received Message: '" + serverMessage + "'");
} catch (Exception e) {
Log.e("TCP", "S: Error", e);
} finally {
//the socket must be closed. It is not possible to reconnect to this socket
// after it is closed, which means a new socket instance has to be created.
socket.close();
}
} catch (Exception e) {
Log.e("TCP", "C: Error", e);
}
}
public interface OnMessageReceived {
public void messageReceived(String message);
}
}
On Server Side in Core Java 在Core Java的服务器端
ServerBoard.java ServerBoard.java
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class ServerBoard extends JFrame
{
private JTextArea messageArea;
private JButton sendButton;
private JTextField message;
private JButton startServer;
private TCPServer mServer;
public ServerBoard(){
super("ServerBoard");
JPanel panelFields = new JPanel();
panelFields.setLayout(new BoxLayout(panelFields,BoxLayout.X_AXIS));
JPanel panelFields2 = new JPanel();
panelFields2.setLayout(new BoxLayout(panelFields2,BoxLayout.X_AXIS));
messageArea = new JTextArea();
messageArea.setColumns(30);
messageArea.setRows(10);
messageArea.setEditable(false);
sendButton = new JButton("Send");
sendButton.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e){
String msg = message.getText();
messageArea.append("\n" + msg);
mServer.sendMessage(msg);
message.setText("");
}
});
startServer = new JButton("Start Server");
startServer.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e){
startServer.setEnabled(false);
mServer = new TCPServer(new TCPServer.OnMessageReceived(){
public void messageReceived(String msg){
messageArea.append("\n" + msg);
}
});
mServer.start();
}
});
message = new JTextField();
message.setSize(200,20);
panelFields.add(messageArea);
panelFields.add(startServer);
panelFields2.add(message);
panelFields2.add(sendButton);
getContentPane().add(panelFields);
getContentPane().add(panelFields2);
getContentPane().setLayout(new BoxLayout(getContentPane(),BoxLayout.Y_AXIS));
setSize(300,170);
setVisible(true);
}
}
TCPServer.java TCPServer.java
import javax.swing.*;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class TCPServer extends Thread
{
public static final int SERVER_PORT = 4444;
private boolean running = false;
private PrintWriter mOut;
private OnMessageReceived mMessageListener = null;
private boolean mRun = false;
PrintWriter out;
public TCPServer(OnMessageReceived listener){
this.mMessageListener = listener;
}
public static void main(String[] args)
{
ServerBoard frame = new ServerBoard();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
public void sendMessage(String message){
if(mOut != null && !mOut.checkError()){
mOut.print(message);
mOut.flush();
}
}
@Override
public void run(){
super.run();
running = true;
try{
System.out.println("S: Connecting...");
ServerSocket serverSocket = new ServerSocket(SERVER_PORT);
Socket client = serverSocket.accept();
System.out.println("S: Receiving...");
try{
mOut = new PrintWriter(new BufferedWriter(new OutputStreamWriter(client.getOutputStream())),true);
BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
while(running){
String msg = in.readLine();
if(msg != null && mMessageListener != null){
mMessageListener.messageReceived(msg);
}
}
}catch(Exception e){
e.printStackTrace();
}
}catch(Exception e){
e.printStackTrace();
}
}
public interface OnMessageReceived
{
public void messageReceived(String message);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.