嗯,这是我的第二篇文章,我正在经历套接字通信TCP / IP这样一个大问题,在Android客户端和PC上运行的java服务器应用程序之间。
我尝试做的是当我从客户端应用程序按下按钮到服务器时发送一个字符串,然后根据我的意愿多次回复我的客户端应用程序,这个结果显示在{{1我的客户。
当我尝试使用我的客户端应用程序连接到服务器时,会出现问题,连接成功执行,但是当我按下按钮并发送数据时,客户端应用程序卡住了,显示结果的唯一方法是停止服务器应用程序。拜托,我需要帮助!我是Android的新手。感谢。
这是简单的服务器代码:
TextView
这是我的Android客户端应用程序的Main.java的一部分(我正在使用向服务器发送“D”字符串的按钮(“状态”按钮)进行探测,服务器发回“ON”作为答案)。
import java.io.*;
import java.net.*;
import java.util.logging.Level;
import java.util.logging.Logger;
public class ServerSocks {
private static ServerSocket myServer;
private static Socket myClient;
private static String msj_ToServer;
public static void main (String args[] ){
try {
System.out.println("Bienvenido:\n");
System.out.println("Por favor ingresar el nº de puerto de comunicación: ");
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
String portNumber_str = in.readLine();
int portNumber = Integer.parseInt(portNumber_str);
myServer = new ServerSocket(portNumber);
if(myServer.isBound() == true){
System.out.println("Iniciando servidor en el puerto: "+portNumber);
}
else{
System.err.println("[E R R O R] : No se pudo crear 'LISTEN SOCKET'");
System.exit(0);
}
while(true){
System.out.println("Esperando algún cliente TCP en el puerto ["+portNumber+"]...");
myClient = myServer.accept();
if (myClient.isConnected()) { // if2
System.out.println("[D A T A] : El cliente ha sido aceptado IP-CLIENT\n"+""+ "IP Client address: "+myClient.getInetAddress());
DataOutputStream outClient = new DataOutputStream(myClient.getOutputStream());
DataInputStream inClient = new DataInputStream(myClient.getInputStream());
msj_ToServer = inClient.readLine();
System.out.println("Ha1 "+msj_ToServer);
try{
if(msj_ToServer.equalsIgnoreCase("D")) {
System.out.println("HO "+msj_ToServer);
outClient.writeBytes("ON");
outClient.flush();
break;
}
}catch(IOException e){
e.printStackTrace();
}
if(msj_ToServer == "B" || msj_ToServer == "b"){
System.out.println(msj_ToServer);
outClient.writeUTF("OFF");
outClient.flush();
break;
}
if(msj_ToServer == "C" || msj_ToServer == "c"){
System.out.println(msj_ToServer);
outClient.writeUTF("xd");
outClient.flush();
break;
}
} // fin while inicio de lectura */
} // fin msj1
} // fin while prueba 3
}// fin if2
} // fin while (true) superior
} catch (IOException ex) {
Logger.getLogger(ServerSocket.class.getName()).log(Level.SEVERE, null, ex);
ex.printStackTrace();
}
}// fin main
} // fin clase ServerSocks
这里我尝试向服务器发送“D”字符串
public class MainActivity extends Activity implements OnClickListener {
private Button ledOnButton;
private Button ledOffButton;
static ToggleButton toggleButton;
static EditText statusEditText;
private Button status;
static TextView prueba;
static Socket clientSocket;
static String data;
static String dato;
static PrintStream os;
static DataInputStream is;
static DataInputStream inputLine;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (android.os.Build.VERSION.SDK_INT > 9) {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}
ledOnButton = (Button) findViewById(R.id.ledOnButton);
ledOnButton.setOnClickListener(this);
ledOffButton = (Button) findViewById(R.id.ledOffButton);
ledOffButton.setOnClickListener(this);
toggleButton = (ToggleButton) findViewById(R.id.toggleButton);
toggleButton.setOnClickListener(this);
status = (Button) findViewById(R.id.statusButton);
status.setOnClickListener(this);
statusEditText = (EditText) findViewById(R.id.statusEditText);
// prueba con textView
prueba = (TextView) findViewById(R.id.textView_Prueba);
} // fin OnCreate
@Override
public void onClick(View arg0) {
AsyncAction object = new AsyncAction();
final String salida_dato;
switch (arg0.getId()) {
case R.id.toggleButton:
if (toggleButton.isChecked()) {
object.conexion_socket();
}
if (!toggleButton.isChecked()) {
object.desconexion_socket();
}
break;
case R.id.ledOnButton:
if ((MainActivity.toggleButton.isChecked())) {
object.ledOnButton();
}
break;
case R.id.ledOffButton:
if ((toggleButton.isChecked())) {
object.ledOffButton();
}
break;
case R.id.statusButton:
这里连接正在后台运行asynchTasks(我想是这样)
if ((toggleButton.isChecked())) {
if (clientSocket != null && os != null && is != null) {
try {
final String responseLine;
// String data = "D";
//os.write(data.getBytes());
os.println("D");
while ((responseLine = is.readLine()) != null) {
System.out.println(responseLine);
runOnUiThread(new Runnable() {
public void run() {
MainActivity.prueba.setText(responseLine);
os.flush();
}
});
break;
}
os.close();
is.close();
clientSocket.close();
} //fin try
catch (UnknownHostException e) {
System.err.println("Trying to connect to unknown host: " + e);
} catch (IOException e) {
System.err.println("IOException: " + e);
}
这是我用来创建套接字连接的连接方法
@Override
protected String doInBackground(Void... args) {
conexion_socket();
...
}//fin doInBackground
如果有人能提供这种沟通的方式,我非常感谢!
答案 0 :(得分:2)
if(myServer.isBound() == true){
此时此情况不可能是错误的。删除测试和else
块。您使用端口号=>构建了ServerSocket
它是受约束的。
else{
System.err.println("[E R R O R] : No se pudo crear 'LISTEN SOCKET'");
System.exit(0);
}
不可达。删除。
while(true){
System.out.println("Esperando algún cliente TCP en el puerto ["+portNumber+"]...");
myClient = myServer.accept();
if (myClient.isConnected()) { // if2
再一次,这不可能是假的。你接受了socket =>它是连接的。不要写无用的测试。
System.out.println("[D A T A] : El cliente ha sido aceptado IP-CLIENT\n"+""+ "IP Client address: "+myClient.getInetAddress());
DataOutputStream outClient = new DataOutputStream(myClient.getOutputStream());
DataInputStream inClient = new DataInputStream(myClient.getInputStream());
msj_ToServer = inClient.readLine();
System.out.println("Ha1 "+msj_ToServer);
try{
if(msj_ToServer.equalsIgnoreCase("D")) {
System.out.println("HO "+msj_ToServer);
outClient.writeBytes("ON");
这里你写的是字节但没有行终止符。客户端中的相应代码使用readLine()
,因此它将永久阻止。在此字符串中添加行终止符。
outClient.flush();
冗余。去掉。 DataOutputStream
没有被缓冲,Socket.getOutputStream()
也没有被缓冲,因此刷新其中任何一个都不会做任何事情。
}catch(IOException e){
e.printStackTrace();
}
if(msj_ToServer == "B" || msj_ToServer == "b"){
System.out.println(msj_ToServer);
outClient.writeUTF("OFF");
下定决心。您在编写字节,行或writeUTF()
使用的特殊格式吗?客户端中的相应代码使用readLine()
。我建议您通过readLine()
或writeUTF()/readUTF()
标准化阅读行。你不能混用它们。
outClient.flush();
见上文。删除。
if(msj_ToServer == "C" || msj_ToServer == "c"){
System.out.println(msj_ToServer);
outClient.writeUTF("xd");
见上文。
outClient.flush();
见上文。
MainActivity.clientSocket = new Socket("192.168.2.80", 30000);
try {
MainActivity.os = new PrintStream(MainActivity.clientSocket.getOutputStream());
MainActivity.is = new DataInputStream(MainActivity.clientSocket.getInputStream());
MainActivity.inputLine = new DataInputStream(new BufferedInputStream(System.in));
} // fin try
catch (IOException e){
System.err.println("algo anda al con los i/o ...");
} // fin catch
没有理由将这些代码行放在try块中。你已经在里面了。
if (MainActivity.clientSocket.isConnected()) {
然而,此时此测试不可能是错误的。如果构造了套接字,则它已连接。
但由于结构不正确的异常处理,它可能是 null 。此后的块应位于前面的封闭try
块中。
一般来说,你应该摆脱所有内部try/catch
块。取决于先前try
块中代码成功的代码应位于try
块内。