java - TCP 发送/接收丢失的字节

标签 java c# sockets networking tcp

我正在使用 C# 为 Windows 创建服务器软件,并使用 Java 创建客户端软件。 它在大多数情况下都运行良好,除了少数我不理解的异常(exception)情况。

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

  1. 客户端请求二进制数据
  2. 服务器以字符串形式响应二进制数据的长度
  3. 客户端收到长度并将其转换为整数并开始读取(长度)字节
  4. 服务器开始写入(长度)字节

它在大多数情况下都有效,但有时客户端应用程序没有收到完整的数据和 block 。服务器总是在写入数据后立即刷新,因此刷新不是问题。

此外,我注意到这通常发生在较大的文件中,小文件(最多 ~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. 发送长度并等待客户端回复“OK”
  2. 开始写入字节

不知道为什么,但它有效。在 while(true) 循环中运行它,它在 4 分钟内连续发送了 1000 次数据,没有任何问题,所以我想它已经修复了。

关于java - TCP 发送/接收丢失的字节,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44475696/

相关文章:

java - golang 中 key 长度为 15360 的 RSA key 对生成速度太慢。需要做些什么来解决这个问题?

java - Junit 5 找不到测试(Spring Boot)

c# - 如何使用 Entity Framework 从mysql获取最后插入的id

c# - 检测 IME(输入法编辑器)是否在 Silverlight 中处于事件状态

java - 在 Java 中,如果我将 DatagramPackets 留在 DatagramSocket 中会发生什么?

java - Bitronix + Spring + Hibernate + Mysql 启动时卡住

java - 无法使用包扩展类

c# - 使用 WIA 在 C# 中使用网络摄像头自动拍照

Python套接字发送问题

Python 双向 TCP 套接字卡在 socket.recv 上