串口工具作为服务端往App发送数据内容时,App这边没有接收到,在我关闭串口工具时,App接收到了,感觉是线程阻塞的问题。后来用Wireshark监控了一下,发现串口工具(服务端)是在一始就发送的,不知道为什么,在我关闭串口工具之后,App端才收到数据内容。然后,我就发现我被readLine()方法给坑了,有没有什么方法解决我一下代码中的readLine()的阻塞问题。
case R.id.submit:
//TODO 把数据提交的方式写在这里
new Thread(new Runnable() {
@Override
public void run() {
String message1 = projName1.getText().toString();
try {
socket = new Socket("192.168.3.50",777); //IP地址、端口号
//向服务器发送消息
out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(),"UTF-8")), true);
out.write(message1);
out.flush();
//接收服务器的消息
br = new BufferedReader(new InputStreamReader(socket.getInputStream(),"UTF-8"));
String info = null;
while ((info = br.readLine())!=null){
projName1.setText(info);
}
//关闭资源
br.close();
out.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
break;
}
}
可以参考一下下面我之前写的,你看接受数据那一部分就行了
private ServerSocket mServerSocket;
private Socket mSocket;
private void openService() {
try {
mServerSocket = null;
mServerSocket = new ServerSocket(5000);//端口号5000
} catch (Exception e) {
e.printStackTrace();
log("服务开启失败");
return;
}
log("服务开启成功");
//启动服务线程
SocketAcceptThread socketAcceptThread = new SocketAcceptThread();
socketAcceptThread.start();
}
/**
* 连接线程
* 得到Socket
*/
class SocketAcceptThread extends Thread {
@Override
public void run() {
try {
//等待客户端的连接,Accept会阻塞,直到建立连接,
//所以需要放在子线程中运行
mSocket = mServerSocket.accept();
mServerSocket.close();//关键是这一步,当ServerSocket收到客户端连接之后,关闭ServerSocket
//启动消息接收线程
log("socket开启中");
startReaderService(mSocket);
log("socket开启成功");
} catch (IOException e) {
e.printStackTrace();
log("socket开启失败");
}
}
}
/**
* 从参数的Socket里获取最新的消息
*/
private void startReaderService(final Socket socket) {
new Thread() {
@Override
public void run() {
runOnUiThread(new Runnable() {
@Override
public void run() {
// MsgInfo msgInfo = new MsgInfo(2, mServerIP, "开启成功");
// msgInfo.setCreatDate(System.currentTimeMillis());
// msgInfo.setCreatTime(getDateToString(msgInfo.getCreatDate()));
// mAdapter.addData(msgInfo);
mBinding.btSend.setEnabled(true);
}
});
DataInputStream reader;
try {
// 获取读取流
reader = new DataInputStream(socket.getInputStream());
while (isOpenService) {
// 读取数据
String msg = reader.readUTF();
log("客户端的信息:" + msg);
//发消息更新UI
Message message = new Message();
message.what = 1;
message.obj = msg;
serviceHandler.sendMessage(message);
try {
SystemClock.sleep(100);
} catch (Exception e) {
e.printStackTrace();
}
}
} catch (Exception e) {
log("断开连接导致异常");
e.printStackTrace();
if (mSocket != null) {
try {
mSocket.close();
} catch (IOException ioException) {
ioException.printStackTrace();
} finally {
mSocket = null;
}
openService();//当前客户端断开连接之后,重新开启ServerSocket,等待连接
}
}
}
}.start();
}
更改为字节读取,不使用行读取。
readLine()在没有读取到换行时。是不会返回的。而是处于阻塞状态。
修改为字节读取,并且修改为available阻塞,这样的话,更加好一些
private class ReadThread extends Thread {
private final int serialPort;
private boolean isStop = false;
public ReadThread(int serialPort) {
this.serialPort = serialPort;
}
public void stopRead() {
isStop = true;
}
@Override
public void run() {
super.run();
while (!isStop) {
synchronized (mLock) {
try {
int count = inputStream.available();
if (count > 0) {
byte[] data = new byte[count];
inputStream.read(data);
}
//休眠10秒,防止空跑
sleep(10);
} catch (Exception e) {
e.printStackTrace();
LogUtils.e(TAG, "receiver data exception " + e.toString());
}
}
}
}
}