Java Android应用程序中套接字DataInputStream BufferedInputStream的错误消息序列
我在接收从另一台设备发送的不规则字节序列消息时遇到问题 设置如下:我有一个Android应用程序(客户端)和带有以太网的实时系统(服务器),两者都通过路由器连接在局域网中,通过原始字节通信 从Android应用程序我发送请求,这会导致服务器响应多条消息-第一条消息有8个字节,下面的消息有27个字节。我已经调试了服务器,我确信它发送的第一条消息是第8字节的消息,然后是其他消息 关于应用程序-我使用主活动处理通过套接字的数据传输,并使用附加线程处理数据接收。 当接收到新数据时,线程通过处理程序向主活动进行post。在本文中,我们称之为解析接收数据的过程 TbProtocolProcessor是我用来处理自定义协议的类。它可以为我创建一个字节数组,作为特定函数的请求发送,并且它有一个状态机来处理来自服务器的预期响应InetHandler是我仅用于处理连接的嵌套类 我的问题是——为什么我的Android应用程序会返回第一条大小为8的消息,但内容与下一条消息类似?有趣的效果是,如果我只发送8字节的消息,而不发送任何其他消息,它将被正确接收并传递到我的应用程序 代码如下:Java Android应用程序中套接字DataInputStream BufferedInputStream的错误消息序列,java,android,multithreading,sockets,Java,Android,Multithreading,Sockets,我在接收从另一台设备发送的不规则字节序列消息时遇到问题 设置如下:我有一个Android应用程序(客户端)和带有以太网的实时系统(服务器),两者都通过路由器连接在局域网中,通过原始字节通信 从Android应用程序我发送请求,这会导致服务器响应多条消息-第一条消息有8个字节,下面的消息有27个字节。我已经调试了服务器,我确信它发送的第一条消息是第8字节的消息,然后是其他消息 关于应用程序-我使用主活动处理通过套接字的数据传输,并使用附加线程处理数据接收。 当接收到新数据时,线程通过处理程序向主活
public class MainActivity extends AppCompatActivity
{
private TbProtocolProcessor tbProtPrcs = null;
private InetHandler inetHandler = new InetHandler(this);
private static Handler msgHandler = new Handler();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tbProtPrcs = new TbProtocolProcessor(this);
}
// Implementation of InetControl interface
public void ConnectToIP(String strIP, int port)
{
inetHandler.AttachToIP(strIP, port);
}
public void Disconnect()
{
inetHandler.DetachFromIP();
}
public void GetFilesList()
{
byte[] data = TbProtocolProcessor.buildFilesGetList();
inetHandler.SendData(data, data.length);
TbProtocolProcessor.setExpectedResult(
TbProtocolProcessor.TB_STATE_WAIT_MUL_FILESLIST,
data[1],
1);
}
private class InetHandler
{
protected static final int cTARGET_PORT_UNASSIGNED = 0xFFFF;
protected String targetIP = null;
protected int targetPort = cTARGET_PORT_UNASSIGNED;
protected boolean isConnected = false;
protected Socket socket = null;
protected DataOutputStream sockStrmOut = null;
protected DataInputStream sockStrmIn = null;
protected Context context = null;
public InetHandler(Context ctx) {
if (ctx != null)
{
context = ctx;
}
}
class ClientThread implements Runnable {
byte[] indata = new byte[100];
int inCntr;
@Override
public void run() {
try {
InetAddress serverAddr = InetAddress.getByName(targetIP);
socket = new Socket(serverAddr, targetPort);
socket.setKeepAlive(true);
// DataOutputStream is used to write primitive data types to stream
sockStrmOut = new DataOutputStream(socket.getOutputStream());
sockStrmIn = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
if (socket.isConnected()) {
isConnected = true;
//Toast.makeText(context, "CONNECTED", Toast.LENGTH_SHORT).show();
//findViewById(R.id.action_connect).setBackgroundColor(0xFF60FF60);
}
} catch (UnknownHostException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
// TODO:
while (isConnected) {
try {
inCntr = sockStrmIn.read(indata);
}
catch (IOException e) {
e.printStackTrace();
}
if (inCntr > 0) {
msgHandler.post(new Runnable() {
@Override
public void run() {
if ( tbProtPrcs.Process(indata, inCntr) ) {
Toast.makeText(context, "Operation Success", Toast.LENGTH_SHORT).show();
}
else {
Toast.makeText(context, "Operation ERROR", Toast.LENGTH_SHORT).show();
}
}
});
}
}
}
}
public void AttachToIP(String sIP, int iPort)
{
if ( (isIPValid(sIP)) && (iPort < cTARGET_PORT_UNASSIGNED) )
{
targetIP = sIP;
targetPort = iPort;
// Start the connection thread
new Thread(new ClientThread()).start();
}
}
public void DetachFromIP()
{
try {
socket.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
public boolean SendData(byte[] data, int size)
{
boolean bResult = false;
try
{
if ( (data != null) && (size > 0) && (sockStrmOut != null) ) {
Toast.makeText(context, "Sending...", Toast.LENGTH_SHORT).show();
sockStrmOut.write(data, 0, size);
bResult = true;
}
} catch (Exception e) {
e.printStackTrace();
}
return bResult;
}
public boolean isIPValid (String ip) {
try {
if (ip == null || ip.isEmpty()) {
return false;
}
String[] parts = ip.split( "\\." );
if ( parts.length != 4 ) {
return false;
}
for ( String s : parts ) {
int i = Integer.parseInt( s );
if ( (i < 0) || (i > 255) ) {
return false;
}
}
return true;
} catch (NumberFormatException nfe) {
return false;
}
}
}
public类MainActivity扩展了AppCompatActivity
{
专用TbProtocolProcessor tbProtPrcs=null;
私有InetHandler InetHandler=新的InetHandler(此);
私有静态处理程序msgHandler=新处理程序();
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tbProtPrcs=新的TbProtocolProcessor(this);
}
//InetControl接口的实现
公共无效连接IP(字符串条,int端口)
{
inetHandler.AttachToIP(条带,端口);
}
公共空间断开连接()
{
inetHandler.DetachFromIP();
}
public void GetFilesList()
{
字节[]数据=TbProtocolProcessor.buildFileGetList();
inetHandler.SendData(data,data.length);
TbProtocolProcessor.setExpectedResult(
TbProtocolProcessor.TB_STATE_WAIT_MUL_FILESLIST,
数据[1],
1);
}
私有类InetHandler
{
受保护的静态最终int-cTARGET\u-PORT\u UNASSIGNED=0xFFFF;
受保护的字符串targetIP=null;
受保护的int targetPort=cTARGET\u PORT\u未分配;
受保护的布尔值未连接=false;
受保护的套接字=空;
受保护的DataOutputStream sockStrmOut=null;
受保护的DataInputStream sockStrmIn=null;
受保护的上下文=null;
公共InetHandler(上下文ctx){
如果(ctx!=null)
{
上下文=ctx;
}
}
类ClientThread实现Runnable{
字节[]indata=新字节[100];
国际贸易中心;
@凌驾
公开募捐{
试一试{
inetAddressServerAddr=InetAddress.getByName(targetIP);
套接字=新套接字(serverAddr,targetPort);
socket.setKeepAlive(true);
//DataOutputStream用于将基本数据类型写入流
sockStrmOut=newdataoutputstream(socket.getOutputStream());
sockStrmIn=newdatainputstream(newbufferedinputstream(socket.getInputStream());
if(socket.isConnected()){
断开连接=正确;
//Toast.makeText(上下文“已连接”,Toast.LENGTH_SHORT).show();
//findViewById(R.id.action_connect).setBackgroundColor(0xFF60FF60);
}
}捕获(未知后异常e1){
e1.printStackTrace();
}捕获(IOE1异常){
e1.printStackTrace();
}捕获(例外e){
e、 printStackTrace();
}
//待办事项:
while(断开连接){
试一试{
inCntr=sockStrmIn.read(indata);
}
捕获(IOE异常){
e、 printStackTrace();
}
如果(增量>0){
msgHandler.post(新的Runnable(){
@凌驾
公开募捐{
if(tbProtPrcs.过程(indata,inCntr)){
Toast.makeText(上下文,“操作成功”,Toast.LENGTH_SHORT).show();
}
否则{
Toast.makeText(上下文,“操作错误”,Toast.LENGTH_SHORT).show();
}
}
});
}
}
}
}
公共无效附件(字符串sIP,int iPort)
{
if((isIPValid(sIP))和&(iPort0)&&&(sockStrmOut!=null)){
Toast.makeText(上下文,“发送…”,Toast.LENGTH_SHORT.show();
sockStrmOut.write(数据,0,大小);
bResult=true;
}
}捕获(例外e){
e、 printStackTrace();
}
返回结果;
}
公共布尔值isIPValid(字符串ip){