所以我在Android中使用套接字来建立连接,然后使用UI中的send_message按钮从EditText字段发送字符串。
我可以建立连接,但是,当我尝试使用sendMessage
发送消息时,客户端和服务器线程都转到语句的catch部分。在代码中参考:
我在其他StackOverflow线程中看到它可能与PrintWriter out
变量及其范围有关吗?
非常感谢您的帮助和反馈
package com.project.jaja.fleetcommander;
import com.project.jaja.fleetcommander.util.SystemUiHider;
import android.app.Activity;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.Enumeration;
public class P2PActivity extends Activity {
//Omitting non-relevant code to with fullscreen
private TextView serverStatus;
// Client IP
public String CLIENTIP;
// SERVER IP
public String SERVERIP = "10.0.2.15";
// DESIGNATE A PORT
public static final int SERVERPORT = 5554;
private Handler handler = new Handler();
private ServerSocket serverSocket = null;
private EditText serverIpField;
private boolean connected = false;
private boolean hosting = false;
public Button sendMessage;
public PrintWriter out = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_p2p);
serverIpField = (EditText) findViewById(R.id.server_ip);
serverStatus = (TextView) findViewById(R.id.server_status);
sendMessage = (Button) findViewById(R.id.send_button);
//Omitting non-relevant code to do with fullscreen
}
//Omitting non-relevant code to do with fullscreen
public void clickServer(View view) {
SERVERIP = getLocalIpAddress();
Thread fst = new Thread(new ServerThread());
fst.start();
hosting = true;
Button serverButton = (Button) findViewById(R.id.server_button);
serverButton.setEnabled(false);
}
public void clickClient(View view) {
if (!connected) {
SERVERIP = serverIpField.getText().toString();
CLIENTIP = getLocalIpAddress();
if (!SERVERIP.equals("")) {
Thread cThread = new Thread(new ClientThread());
cThread.start();
}
}
}
public class ServerThread implements Runnable {
public void run() {
try {
if (SERVERIP != null) {
handler.post(new Runnable() {
@Override
public void run() {
serverStatus.setText("Listening on IP: " + SERVERIP);
}
});
serverSocket = new ServerSocket(SERVERPORT);
while (true) {
// LISTEN FOR INCOMING CLIENTS
Socket client = serverSocket.accept();
CLIENTIP = client.getInetAddress().getHostAddress();
handler.post(new Runnable() {
@Override
public void run() {
serverStatus.setText("Connected.");
}
});
try {
BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
String line = null;
out = new PrintWriter(client.getOutputStream(), true);
sendMessage.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
EditText message = (EditText) findViewById(R.id.message_field);
out.println(message.getText().toString());
message.setText("");
}
});
connected = true;
while (connected) {
line = in.readLine();
if (line.equals("GAME END")) {
serverSocket.close();
} else {
serverStatus.setText(line);
}
}
break;
} catch (Exception e) {
handler.post(new Runnable() {
@Override
public void run() {
serverStatus.setText("Oops. Connection interrupted. Please reconnect your phones.");
}
});
e.printStackTrace();
}
}
} else {
handler.post(new Runnable() {
@Override
public void run() {
serverStatus.setText("Couldn't detect internet connection.");
}
});
}
} catch (Exception e) {
handler.post(new Runnable() {
@Override
public void run() {
serverStatus.setText("Error");
}
});
e.printStackTrace();
}
}
}
// GETS THE IP ADDRESS OF YOUR PHONE'S NETWORK
public static String getLocalIpAddress() {
try {
for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) {
NetworkInterface intf = en.nextElement();
for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) {
InetAddress inetAddress = enumIpAddr.nextElement();
if (!inetAddress.isLoopbackAddress() && inetAddress instanceof Inet4Address) {
return inetAddress.getHostAddress();
}
}
}
} catch (SocketException ex) {
ex.printStackTrace();
}
return null;
}
@Override
protected void onStop() {
super.onStop();
try {
// MAKE SURE YOU CLOSE THE SOCKET UPON EXITING
if (serverSocket != null) {
serverSocket.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
public class ClientThread implements Runnable {
public void run() {
try {
InetAddress serverAddr = InetAddress.getByName(SERVERIP);
try {
Socket socket = new Socket(serverAddr, SERVERPORT);
connected = true;
while (connected) {
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String input = in.readLine();
out = new PrintWriter(socket.getOutputStream(), true);
sendMessage.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
EditText message = (EditText) findViewById(R.id.message_field);
out.println(message.getText().toString());
message.setText("");
}
});
if (input.equals("GAME END")) {
connected = false;
} else {
serverStatus.setText(input);
}
}
socket.close();
serverStatus.setText("socket closed");
Log.d("ClientActivity", "C: Closed.");
} catch (Exception e) {
serverStatus.setText("except");
Log.e("ClientActivity", "S: Error", e);
}
} catch (Exception e) {
Log.e("ClientActivity", "C: Error", e);
}
}
}
}
本质上,代码的目的不是在客户端和服务器之间区分太多。