Java StreamCorruptedException格式错误

Java StreamCorruptedException格式错误,java,android,multithreading,sockets,io,Java,Android,Multithreading,Sockets,Io,我一直在试图解决这个问题,我阅读了stackoverflow(和其他网站)上的其他帖子,但找不到答案 基本上,我正在开发一个通过套接字发送apk文件的应用程序。在开始发送文件之前,我还发送了一个包含应用程序名称和相应apk文件大小的字符串 当我创建套接字(就在Begging的右边)时,我还发送两条消息,一条从客户端发送到服务器,说它的昵称,另一条从服务器发送到客户端,只是说你好。这些信息发送得很好 问题是当我尝试读取appName和文件大小时 编辑:刚刚注意到错误格式异常后显示的字符不是来自错误

我一直在试图解决这个问题,我阅读了stackoverflow(和其他网站)上的其他帖子,但找不到答案

基本上,我正在开发一个通过套接字发送apk文件的应用程序。在开始发送文件之前,我还发送了一个包含应用程序名称和相应apk文件大小的字符串

当我创建套接字(就在Begging的右边)时,我还发送两条消息,一条从客户端发送到服务器,说它的昵称,另一条从服务器发送到客户端,只是说你好。这些信息发送得很好

问题是当我尝试读取appName和文件大小时

编辑:刚刚注意到错误格式异常后显示的字符不是来自错误。它的变化取决于我尝试发送的应用程序

这是我的密码

这是内部类clientHandler(Runnable)的run方法,在这里我在客户端创建流对象

public void run() {
    System.out.println("ServerComm clientHandler - inside the thread run ..");
    try {
        this.in=new ObjectInputStream(socket.getInputStream());//criar os streams para cada um dos clientes
        this.out=new ObjectOutputStream(socket.getOutputStream());
        try{
            System.out.println("SErverComm clientHandler - going to read the nickname.");
            String message = (String)this.in.readObject();
            String[] tmp=message.split(";:-");
            this.nickname=tmp[1];
            System.out.println("ServerComm clientHandler - the nickname of this person is : "+nickname);
            this.out.writeObject("Hello i am the server");
            System.out.println("serverComm clientHandler - just sent my message of hello from the server");
            handshakeDone=true;
            System.out.println("serverComm ClientHandler - the handshake is done ! ");
            connectedClients.put(nickname,this);
            ReceiveThread rec = new ReceiveThread(this);
            new Thread(rec){}.start();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}
然后我启动接收线程,它也是一个内部的可运行类代码:

private ClientHandler clientHandler;

public ReceiveThread(ClientHandler clientHandler) {
    this.clientHandler = clientHandler;
}

@Override
public void run() {
    try {
        ObjectInputStream in = clientHandler.getIn();
        while(!serverSocket.isClosed()){
            try {
                System.out.println("Highway server comm receive thread - INSIDE THE WHILE CICLE, before the in.readObject");
                if(in==null){
                    System.out.println("serverComm - receiveThread the in object is null I am null");
                }
                if(handshakeDone){
                    System.out.println("The handshake was already done before, so lets start receiving !");

                    List<HighwayGridViewAppItem> listOfReceivedFiles=new ArrayList<HighwayGridViewAppItem>();

                    System.out.println("ServerComm receive thread - i am going to try to receive the filesize and name ! ");

                    String fileSizeAsString=(String)in.readObject();
                    System.out.println("Received this initial message with the size: " + fileSizeAsString);
                    String[] valor=fileSizeAsString.split(":");
                    String receivedApkName=valor[0]; //duplicated line pq acho que o nome da app n devia sofrer trim, nao vale a pena.
                    long fileSize=Long.parseLong(valor[1].trim());
                    System.out.println(" ServerComm receive thread : FileSize is at : "+fileSize + " o nome da app e  : "+ receivedApkName);
                    File apkReceived = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/"+receivedApkName + ".apk");
                    int i=1;
                    while(apkReceived.exists()){
                        apkReceived=new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/"+receivedApkName + "("+i+")"+".apk");
                        i++;
                    }
                    i=1;
                    byte[] buffer = new byte [8192];
                    FileOutputStream fos=new FileOutputStream(apkReceived);
                    int count=0;
                    int total=0;//so apra ir vendo quanto recebi.
                    while(total<=fileSize && (count = in.read(buffer)) != -1){
                        fos.write(buffer,0,count);
                        total+=count;
                        System.out.println("Server Comm receive thread - already received this ammount : "+total);
                        if(total==fileSize){
                            System.out.println("Reached the end of the file  !");
                            total++;
                            System.out.println("Receive Thread ServerComm o canonical Path que ta e  : " + apkReceived.getCanonicalPath());
                            HighwayGridViewAppItem aux=new HighwayGridViewAppItem(null, receivedApkName, apkReceived.getCanonicalPath());
                            listOfReceivedFiles.add(aux);
                        }
                    }

                    System.out.println("Already received everything ! ");
                    listOfApps=listOfReceivedFiles;
                    System.out.println("ServerComm : O size da lista de apps que recebi e que agora mudei para que possa reenviar pos outros ta a : "+listOfApps.size());
                    String clientName=clientHandler.getNickname();
                    SendThread sendThread = new 
                    new Thread(sendThread){
                    }.start();

                }

            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }

    } catch (IOException e) {
        e.printStackTrace();
    }
}
这是我尝试读取appName和文件大小(字符串)的地方

如果你们愿意,我也可以发布客户端,但我知道它工作正常,它会发送文件。 我也不知道为什么在堆栈中它也指向clientHandler线程的run方法,它不应该。在clientHandler之前,还有另一个线程接受客户机套接字,然后启动clientHandler,将套接字作为参数

这是我的客户代码:

我有一个连接处理程序嵌套类,只处理流对象和套接字的创建

    public class ConnectionHandler implements Runnable{

    @Override
    public void run() {
        try {
            clientSocket = new Socket (serverIP,porto);
            out = new ObjectOutputStream(clientSocket.getOutputStream());
            in= new ObjectInputStream(clientSocket.getInputStream());
            System.out.println("client comm receive thread - doing the Initial handshake");
            System.out.println("CLientComm connection handler : sending my initial message hello  - my nickname is : "+nickname);
            out.writeObject("Nickname:-:"+nickname);
            System.out.println("ClientComm : Just sent my initial message.");

            try {
                String message = (String) in.readObject();
                System.out.println("ClientComm :_ jist read : " + message   );
                System.out.println("Client Comm receive thread - receive the handshake message from the server. Handshake is done.");
                handshakeDone=true;


                ReceiveThread receiveThread = new ReceiveThread();
                new Thread(receiveThread).start();

            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }

        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}
在这里,我启动接收线程,它将等待接收消息,但在布局中,我有一个发送按钮,它将发送一个choosen apk(它将使用ACTION=“send”再次运行此服务,然后使用onstart命令,如果操作是send,则运行线程SendThread)

以下是该sendTread的代码:

     public class SendThread implements Runnable{

    @Override
    public void run() {
        try {
            //percorrer a lista de apps a enviar
            File apkToSend;
            long apkToSendSize;

            for(int i=0;i<listOfApps.size();i++){
                HighwayGridViewAppItem tmp=listOfApps.get(i);
                filePath=tmp.getFilePath();
                appName=tmp.getAppName();

                apkToSend=new File(filePath);

                if(apkToSend.exists()){

                    apkToSendSize=apkToSend.length();
                    String apkSize=Long.toString(apkToSendSize);
                    System.out.println(appName +": " +apkSize);
                    out.writeObject(""+appName +": "+ apkSize);//appName to send to have the name of the file
                    System.out.println("ClientComm send thread : going to send this "+appName+": "+apkSize);
                    byte[] buffer = new byte [8192];
                    BufferedInputStream bis=new BufferedInputStream(new FileInputStream(apkToSend));
                    int count;
                    int total=0; // so para testes - para saber quanto enviei.
                    while((count=bis.read(buffer))!=-1){
                        System.out.println("buffer values :  " + buffer[0]);
                        out.write(buffer,0,count);
                        total+=count;
                        out.reset();
                        System.out.println("Client Comm send thread - already sent this ammount : "+total);
                    }
                    out.flush();
                    bis.close();

                    try {
                        System.out.println("Just sent the app  : "+appName);
                        Thread.sleep(1000);//just to separate each file, to make sure there are no problems with the other side receiving and this one sending
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }else{
                    System.out.println("There was a problem with the file, the path was incorrect, probably.");
                }

            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

请注意,之前,在处理连接的线程上(clientHandler和ConnectionHandler)我正在成功发送和交易我想要的数据。问题只出现在下面的线程上。

堆栈跟踪没有错误。这是你的期望。你肯定需要发布丢失的客户端代码。已经从客户端添加了代码。我真的需要帮助,我一直在搜索并尝试解决它好几天了。我发现了一些有趣的问题,不知道这是否是问题所在……也许任何读过这篇文章的人都可能知道……我注意到在连接处理程序线程或clientHandler线程(其中inputStreams和outputstreams是本地的)中“交易”的消息工作很好,但是我尝试的第一个,我必须使用一个我必须通过get方法获得的流(因为它在另一端),不工作。这可能是问题的原因吗?如果是,我如何解决它?
    public class ConnectionHandler implements Runnable{

    @Override
    public void run() {
        try {
            clientSocket = new Socket (serverIP,porto);
            out = new ObjectOutputStream(clientSocket.getOutputStream());
            in= new ObjectInputStream(clientSocket.getInputStream());
            System.out.println("client comm receive thread - doing the Initial handshake");
            System.out.println("CLientComm connection handler : sending my initial message hello  - my nickname is : "+nickname);
            out.writeObject("Nickname:-:"+nickname);
            System.out.println("ClientComm : Just sent my initial message.");

            try {
                String message = (String) in.readObject();
                System.out.println("ClientComm :_ jist read : " + message   );
                System.out.println("Client Comm receive thread - receive the handshake message from the server. Handshake is done.");
                handshakeDone=true;


                ReceiveThread receiveThread = new ReceiveThread();
                new Thread(receiveThread).start();

            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }

        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}
     public class SendThread implements Runnable{

    @Override
    public void run() {
        try {
            //percorrer a lista de apps a enviar
            File apkToSend;
            long apkToSendSize;

            for(int i=0;i<listOfApps.size();i++){
                HighwayGridViewAppItem tmp=listOfApps.get(i);
                filePath=tmp.getFilePath();
                appName=tmp.getAppName();

                apkToSend=new File(filePath);

                if(apkToSend.exists()){

                    apkToSendSize=apkToSend.length();
                    String apkSize=Long.toString(apkToSendSize);
                    System.out.println(appName +": " +apkSize);
                    out.writeObject(""+appName +": "+ apkSize);//appName to send to have the name of the file
                    System.out.println("ClientComm send thread : going to send this "+appName+": "+apkSize);
                    byte[] buffer = new byte [8192];
                    BufferedInputStream bis=new BufferedInputStream(new FileInputStream(apkToSend));
                    int count;
                    int total=0; // so para testes - para saber quanto enviei.
                    while((count=bis.read(buffer))!=-1){
                        System.out.println("buffer values :  " + buffer[0]);
                        out.write(buffer,0,count);
                        total+=count;
                        out.reset();
                        System.out.println("Client Comm send thread - already sent this ammount : "+total);
                    }
                    out.flush();
                    bis.close();

                    try {
                        System.out.println("Just sent the app  : "+appName);
                        Thread.sleep(1000);//just to separate each file, to make sure there are no problems with the other side receiving and this one sending
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }else{
                    System.out.println("There was a problem with the file, the path was incorrect, probably.");
                }

            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
    out.writeObject(""+appName +": "+ apkSize);//appName to send to have the name of the file