- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
好吧,这是我的第二篇文章,我正在经历 Android 客户端和运行在 PC 上的 Java 服务器应用程序之间的套接字通信 TCP/IP 的一个大问题。
我尝试做的是当我从客户端应用程序按下一个按钮到服务器时发送一个字符串,然后根据需要多次向我的客户端应用程序返回一个答案,这个结果显示在 我客户的 TextView
。
当我尝试使用我的客户端应用程序连接到服务器时出现问题,连接成功执行,但是当我按下按钮并发送数据时,客户端应用程序卡住了,显示结果的唯一方法是停止服务器应用程序。拜托,我需要帮助!我是安卓新手。谢谢。
这是简单的服务器代码:
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
这是我的 Android 客户端应用程序的 Main.java 的一部分(我正在使用向服务器发送“D”字符串并且服务器发回“ON”的按钮(“状态”按钮)进行探测作为答案)。
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:
这里我尝试向服务器发送一个“D”字符串
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);
}
这里的连接是在后台运行的 asynchTasks(我认为是这样)
@Override
protected String doInBackground(Void... args) {
conexion_socket();
...
}//fin doInBackground
这是我用来创建套接字连接的连接方法
public void conexion_socket(){
try {
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
} catch (IOException e) {
e.printStackTrace();
}
if (MainActivity.clientSocket.isConnected()) {
MainActivity.statusEditText.setText("OK connection");
}
}
如果有人能提供一种进行这种交流的方法,我将不胜感激!
最佳答案
if(myServer.isBound() == true){
在这一点上这不可能是错误的。删除测试和 else
block 。您使用端口号构造了 ServerSocket
=> 它已绑定(bind)。
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");
这里你写的是字节但没有行终止符。客户端中对应的代码使用的是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 block 中。你已经在里面了。
if (MainActivity.clientSocket.isConnected()) {
再一次,这个测试在这一点上不可能是错误的。如果构造了套接字,则它已连接。
但是,由于您的异常处理结构不正确,它可以是null。这之后的 block 应该在前面封闭的 try
block 内。
一般来说,你应该去掉所有内部的 try/catch
block 。依赖于先前 try
block 中代码成功的代码应该在该 try
block 中。
关于java - socket - Android 客户端 - Java 服务器 PC 卡住,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37176655/
我正在我的 xamarin.forms 应用程序中实现扫描仪功能,为此我正在使用 iOS native AVCaptureSession。但我的问题是在扫描或捕获 session 处于事件状态并且设备
所以我目前正在为我的项目制作一个音乐应用程序,它允许用户创建自己的音乐播放列表。但是,当我单击显示媒体选择器按钮时,它只显示白屏,当包含媒体选择器的 View 是 Initial View Contr
当我尝试在模拟器中启动 AVD 时,会出现一个小窗口(见图片),5 秒后它说没有响应并一直保持这种状态直到我关闭它。 我在网上搜索并尝试了所有解决方案,但都没有成功 在 BIOS 中启用了虚拟化 已安
尝试使用以下命令从视频中提取特定帧(删除了文件的特定名称!: ffmpeg -i video.mp4 -vf "select-gte(n\,6956)"-vframes 10262 文件夹/帧%d.j
我怎么知道终端正在继续工作而不中断它? 我已经运行了以下 git 命令: clone git://ligo-vcs.phys.uwm.edu/lalsuite.gituote 一段时间后它似乎被卡住了
我对 WPF 中的数据网格有一个奇怪的问题。我正在为我的应用程序使用 MVVM 模式,并且我的 View 模型实现了 idataerrorinfo 接口(interface)。每当我在添加新行后在我的
我有这个 Excel 文件,当我输入数据时它卡住了。例如,我双击一个单元格,输入数据,然后按“输入”。它会卡住而不是进入下面的细胞。按几次“enter”不会解冻程序,唯一有效的是用鼠标选择另一个单元格
我有线程池的任务队列,每个任务都有卡住锁定其正在使用的所有资源的倾向。并且除非重新启动服务,否则这些无法释放。 ThreadPool 中有没有办法知道它的线程已经被卡住?我有一个使用超时的想法(虽然我
我制作了以下小程序来确定内存是否用于 freeze(X,Goal) 之类的目标回收时 X变得无法访问: %:- use_module(library(freeze)). % Ciao Prolog n
我有一个使用 swing 的简单 java 应用程序。然而,当我执行程序时,框架将会出现,但我无法单击任何地方,并且按钮仅在几秒钟后出现。我对 javas Swing 库非常陌生,所以我可能会丢失一些
我正在尝试创建一个简单的 TCP 客户端服务器应用程序接口(interface)用户可以在按下相应按钮时启动或停止服务器我创建了一个 StartServer 按钮,当用户按下按钮时它应该连接到服务
我正在尝试从 ftp 服务器下载文件,但在检索文件时卡住了。我正在使用 commons-net-3.6.jar 我注意到的事情 当我使用 ftpClient.enterRemotePassiveMod
我正在尝试编写一个函数,该函数将能够找到位于我系统上的可执行文件搜索路径中的任意可执行文件。我遇到了一些输入会导致 SearchPathW 的问题无限期地卡住,我不确定到底发生了什么。 std::op
我的 Nativescript 应用程序的许多页面中都有 RadSideDrawer。主应用程序组件有一个 page-router-outlet并且所有其他页面都通过导航加载到此组件中。带抽屉的页面包
我有一个最小的服务器,它等待客户端连接,然后他启动一个线程,将回复发送回客户端,问题是回复。 这是服务器的代码: int port = 1234; ServerSocket servSock =
我有一个使用 C# 的 WinForms 应用程序。我尝试从文件中读取一些数据并将其插入到数据表中。虽然此操作很忙,但我的表单卡住并且我无法移动它。有谁知道我该如何解决这个问题? 最佳答案 这可能是因
在我们学校最新的项目中,我遇到了一些问题。我想观察新条目的路径,该路径是由文件导向器按钮选择的,但如果我选择任何文件,整个窗口都会卡住...我猜它被卡住,因为调用了“observePath”方法,但我
当我输入一百万作为输入数字时,我的程序卡住了。我该如何解决这个问题? 我尝试将第二个 for 循环分离为第二个函数,但没有成功。 import java.io.*; public class Arra
早上好编译我的应用程序时,我在 Android Studio 上遇到问题。我在构建时没有收到关于 app:transformClassesWithDexBuilderForDebug 的任何输出错误,
我正在使用以下触发器 DELIMITER ; CREATE TRIGGER updateCount AFTER INSERT ON user_info FOR EACH ROW BEGIN UPDA
我是一名优秀的程序员,十分优秀!