Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java数据通过套接字传输。如何使发送者和接收者保持在";同步“;_Java_Sockets_Buffer - Fatal编程技术网

Java数据通过套接字传输。如何使发送者和接收者保持在";同步“;

Java数据通过套接字传输。如何使发送者和接收者保持在";同步“;,java,sockets,buffer,Java,Sockets,Buffer,我想实现一种将数据从一个客户机传输到另一个客户机的简单方法。 实现本身不是问题——它已经起作用了。我对发送方的实际传输速率有问题 当您使用[put your desired chat/filetransfer program here]向另一个客户端发送文件时,您都知道进度条。您可以看到已传输的字节和要传输的剩余字节,以及传输完成之前的估计时间。我也尝试实现同样的东西,但似乎中间的缓冲区有问题。 虽然发送缓冲区是一个很好的特性,但它会极大地影响测量到的到其他客户端的传输速率。开始转移时,我得到了

我想实现一种将数据从一个客户机传输到另一个客户机的简单方法。 实现本身不是问题——它已经起作用了。我对发送方的实际传输速率有问题

当您使用[put your desired chat/filetransfer program here]向另一个客户端发送文件时,您都知道进度条。您可以看到已传输的字节和要传输的剩余字节,以及传输完成之前的估计时间。我也尝试实现同样的东西,但似乎中间的缓冲区有问题。 虽然发送缓冲区是一个很好的特性,但它会极大地影响测量到的到其他客户端的传输速率。开始转移时,我得到了几乎无限的Bps,在转移过程中Bps缓慢减少,但从未达到真正转移的位置。 其效果是发送方可视地完成发送文件,而接收方仍在接收字节。这是我需要避免的(由于其他原因)完全不同步的发送方和接收方

我第一次尝试发送的文件如下(伪代码):

这在所描述的发送方和接收方完全去同步的情况下结束

我的下一次尝试是:

while(still bytes left to read) {
    Sender reading Byte-Array from InputStream (aka FileInputStream or something else)
    Sender write and flushes this Byte-Array to the SocketOutputStream
    Sender wait for ACK-Paket from Receiver
}
因此,发送方将字节数组写入线路,并等待来自接收方的小ACK Paket。收到ACK后,发送方发送下一个字节数组。 虽然这在慢速连接(即WAN到internet的连接)上可以正常工作,但在LAN连接上却非常慢。 我得出的结论是,我不喜欢ACK的想法,但我也不喜欢去同步的情况。 其他客户如何解决这种情况?是否有一种方法可以禁用缓冲区,以便
outputStream.write(byte[])
只需导线传输数据所需的时间,或者是否有任何其他机制可以“查看”实际传输的字节数

提前谢谢


Martin

不要显示您发送的内容,而是显示另一端告诉您它已收到的内容。i、 e.另一端可以发回它已接收的字节数。这样,您的进度条将略微悲观,而不是真正乐观。

您的问题是,您试图将您试图读取的整个数组作为单个对象发送。在发送端,你得到一个大数组,调用
write
,然后调用
flush
,它发送整个数组并等待刷新(其间没有你的控制,所以你发送的应用程序无法显示进度)。在接收端,你会遇到同样的问题。您可能只需调用
read
,它将在一次操作中读取整个ArrayList

很可能,在尝试将数据作为大数组发送之前,您能够读取大量数据

如果将数组分成合理的“块”(可能是一个简单的
max(1024,arraysize/100)
),则可以获得一些控制权。然后一块一块地发送。伪代码如下所示:

chunkSize = max(1024, arraysize/100)
while(still bytes left to read) {
    Sender reading chunkSize bytes into Byte-Array from InputStream
    Sender write and flushes this Byte-Array to the SocketOutputStream
    reportProgress()
}

这就是TCP工作的方式,你在浪费时间,中间有缓冲和其他延迟,你永远无法控制或影响。目标不是一个好的同步显示,目标是尽快传输数据。您不希望为了使GUI看起来美观而减慢发送或接收速度或使发送或接收复杂化(例如,通过ACK数据包或@PeterLawrey的建议)。重新思考。我只会跟踪发送的输入,例如
FileInputStream。
NB您不应该在循环内刷新。@EJP:PeterLawrey建议的解决方案不会减慢传输本身。发送方通过一个线程发送数据,并通过另一个线程接收数据。所以数据会尽快传输。感谢您的其他提示,不要在循环内刷新。我会按照你的建议行事。OP的问题中不会出现
ArrayList
Object
这两个词。对ArrayList表示歉意(一定是误读了它本身)。答案的其余部分可能仍然有效(可能是OP读取的字节数组太大,然后通过writeObject调用将其发送)。谢谢您的回答。但是,我已经读取了较小的数据块(chunk),并将这些较小的数据块发送到wire。感谢您的建议。我已经实现了你提到的来自接收者的“更新消息”,并显示这些信息,而不是发送者自己的信息。这样一切都如预期的那样!
chunkSize = max(1024, arraysize/100)
while(still bytes left to read) {
    Sender reading chunkSize bytes into Byte-Array from InputStream
    Sender write and flushes this Byte-Array to the SocketOutputStream
    reportProgress()
}