从输入流读取的第二个数据包具有不完整的数据,

时间:2015-05-09 00:33:48

标签: java sockets networking tcp

我是一个使用TCP接收字节的简单服务器,然后将它们保存到文件流中。通过许多测试,我看到收到的第一个数据包始终只是文件名而没有其他数据。收到的第二个数据包只有一个字节,它是输入文本文件的第一个字母。在这之后所有数据包都被正确发送,但我似乎无法弄清楚是什么搞乱了第二个数据包。似乎最后一个数据包被写入两次。谁能看到我做错了什么?以下是输入/输出示例:https://www.diffchecker.com/srclclrx

    InputStream in = clntSock.getInputStream(); //server's input stream - gets data from the client
        OutputStream out = clntSock.getOutputStream(); //server's output stream - server sends data to the client

        byte[] byteBuffer = new byte[BUFSIZE];
        int count = in.read(byteBuffer, 0, BUFSIZE);
        String firstRead = new String(byteBuffer, 0, count);
        int fileNameEnd = firstRead.indexOf("\r\n");
        String fileName = firstRead.substring(0, fileNameEnd);

        FileOutputStream fout = new FileOutputStream(fileName); //unzipped file output stream

        int contentBegin = fileNameEnd+2;
        byte[] oldBuffer = Arrays.copyOfRange(byteBuffer, contentBegin, count);
        int oldCount = count-contentBegin;
        String oldString = new String(byteBuffer, contentBegin, count-contentBegin, "US-ASCII");

        while((count = in.read(byteBuffer, 0, BUFSIZE)) != -1) { // read from origin's buffer into byteBuffer until origin is out of data
            String newString = new String(byteBuffer, 0, count, "US-ASCII");
            String combinedString = oldString + newString;
            int index = combinedString.indexOf("--------MagicStringCSE283Miami");
            if(index != -1){
                System.out.println("Final Print");

                byte[] combinedBuffer = concat(oldBuffer, byteBuffer);

                for(int i=0; i<index; i++){
                    System.out.print((char)combinedBuffer[i]);
                }
                System.out.println("");

                fout.write(combinedBuffer, 0, index);
                fout.flush();
                fout.close();
                break;
            }
            System.out.println(+ oldCount);
            fout.write(oldBuffer, 0, oldCount); //write the byteBuffer's data to the client via the zip output stream
            fout.flush(); //push all data out of the zipOutputStream before continuing
            if(count == 1){
                for(int i=0; i<count; i++){
                    System.out.println((char)byteBuffer[i]);
                }
            }

            oldBuffer = byteBuffer;
            oldCount = count;
            oldString = newString;
        }

编辑:我的另一个特点是倒数第二个数据包始终只是&#34; - &#34;然后最后一个数据包具有终止文件输出流的魔术字符串的剩余部分。

2 个答案:

答案 0 :(得分:1)

您确定要获取所收到数据的全部内容吗?

string fullPlainText = new TextRange(richTextBox.Document.ContentStart, richTextBox.Document.ContentEnd).Text;

很可能在你的逻辑中,你是在误解你收到的东西,并以某种方式丢失部分数据。 例如,您声称仅接收“ - ”的第二个数据包是计数,那么只等于1?事实上TCP可能就是这种情况,但你必须确认你确实正在处理你收到的所有内容。根据您的解释,我认为您正在丢弃数据,而不是正确处理它。

答案 1 :(得分:0)

TCP中没有消息,也不保证每个read()将返回多少数据。除非发生错误,否则仅指定在阻塞模式下传输至少一个字节。

其中一个后果是,如果不将read()的结果存储在变量中,对其进行测试,然后使用它来分隔处理的数据量,就不可能编写正确的网络代码。

你的期望是错误的。