TCP发送/接收丢失的字节

时间:2017-06-10 16:40:50

标签: java c# sockets networking tcp

我正在使用C#为Windows和Java创建服务器软件来创建客户端软件。 它在大多数情况下都能正常工作,除了那些我不理解的例外情况。

我通常在两端使用.ReadLine()和.WriteLine()进行通信,除非我尝试发送二进制数据。那是我直接写入和读取字节的时候。 这就是软件的工作方式:

  1. 客户请求二进制数据
  2. 服务器以二进制数据的长度作为字符串
  3. 进行响应
  4. 客户端收到长度并将其转换为整数并开始读取(长度)字节
  5. 服务器开始写入(长度)字节
  6. 它适用于大多数情况,但有时客户端应用程序不会收到完整的数据和块。写入数据后服务器总是立即刷新,因此刷新不是问题。

    此外,我注意到这通常发生在较大的文件中,小文件(最大约1 MB)通常不是问题。

    注意 C#服务器似乎确实完全发送了数据,所以问题很可能出现在Java代码中。

    编辑 - 以下是客户端的一些日志

    工作下载pastebin.com/hFd5TvrF

    下载失败pastebin.com/Q3zFWRLB

    似乎客户端在结尾处等待2048个字节(在这种情况下应该是length - processed = 2048),但由于某种原因客户端阻塞。

    任何想法我做错了什么?以下是服务器和客户端的源代码:

    C#服务器:

    public void Write(BinaryWriter str, byte[] data)
    {
        int BUFFER = 2048;
        int PROCESSED = 0;
        // WriteString sends the String using a StreamWriter (+ flushing)
        WriteString(data.Length.ToString());
        while (PROCESSED < data.Length)
        {
            if (PROCESSED + BUFFER > data.Length)
                BUFFER = data.Length - PROCESSED;
    
            str.Write(data, PROCESSED, BUFFER);
            str.Flush();
    
            PROCESSED += BUFFER;
        }
    }
    

    Java客户端:

    public byte[] ReadBytes(int length){
        byte[] buffer = new byte[length];
        int PROCESSED = 0;
        int READBUF = 2048;
        TOTAL = length;
        progress.setMax(TOTAL);
        InputStream m;
        try {
            m = clientSocket.getInputStream();
            while(PROCESSED < length){
                if(PROCESSED + READBUF > length)
                    READBUF = length - PROCESSED;
    
                try {
                    PROCESSED += m.read(buffer, PROCESSED, READBUF);
                } catch (IOException e) {
                }
                XPROCESSED = PROCESSED;
            }
        } catch (IOException e1) {
            // Removed because of sensitive data
        }
    
        return decryptData(buffer);
    }
    

1 个答案:

答案 0 :(得分:0)

我找到了解决办法。截至目前,服务器在发送字节数组后发送长度。出于某种原因,这不起作用。

所以我改变的是:

  1. 发送长度并等待客户回复“确定”
  2. 开始写字节
  3. 不确定原因,但确实有效。把它放在一个while(true)循环中,并且它在4分钟内发送数据1000次并没有问题,所以我想这是固定的。