通过NetworkStream读取ZlibStream在C#Net中给出阻塞问题

通过NetworkStream读取ZlibStream在C#Net中给出阻塞问题,c#,.net,compression,zlib,networkstream,C#,.net,Compression,Zlib,Networkstream,我有一个TCP上的网络流,它是一个Zlib流,两种方式(客户端到服务器和服务器到客户端) 对于Zlib,我使用的是最新的Ionic.Zlib.dll 对于发送/接收的前两个数据包,它工作正常,但当接收到第三个数据包左右时,它开始出现异常 ZlibStream上的每个读取操作都会阻塞,直到数据包被另一端重复 例如: // Where reader is a BinaryReader on the ZlibStream on the NetworkStream int a = reader.Read

我有一个TCP上的网络流,它是一个
Zlib
流,两种方式(客户端到服务器和服务器到客户端)

对于
Zlib
,我使用的是最新的
Ionic.Zlib.dll

对于发送/接收的前两个数据包,它工作正常,但当接收到第三个数据包左右时,它开始出现异常

ZlibStream
上的每个读取操作都会阻塞,直到数据包被另一端重复

例如:

// Where reader is a BinaryReader on the ZlibStream on the NetworkStream
int a = reader.ReadInt32(); // blocks until initial packet that is 12 bytes is received
int b = reader.ReadInt32(); // blocks until the packet is repeated
int c = reader.ReadInt32(); // blocks until the packet is repeated again
在该代码之后,数据包实际上已经发送了3次,并且只收到了一次

为什么它在那里阻塞?我如何才能让它不阻塞并按预期继续


Zlib的法拉盛与此有关吗?(每个数据包之后都会刷新流。)

Zlib以及其他压缩算法对数据块进行操作。它缓冲来自源流的一些数据,然后尝试对其进行压缩

如果您输入的ZlibStream数据小于缓冲区大小,那么ZlibStream实际上不会立即输出任何内容。在缓冲区填满之前,您的数据将一直保存在那里。为了压缩数据,刷新原始流,甚至可能是压缩流,是不够的

如果SERVICE关闭ZlibStream,那么您的所有readInt都应该接收正确的数据

如果您想实时接收来自服务器的数据包,请先尝试完全压缩数据包,然后通过网络流发送它们。

首先,您可以这样说

“ZlibStream上的每个读取操作都会阻塞,直到数据包被删除 另一端重复。”

这意味着你的服务器上有一个读取。。。图案应该是

Client: Connects to server, asks for data
Server: Sends packet
Client: Reads packet
Client: Sends same packet back
Server: Reads Packet
Server: Sends new packet?
如果是这种情况,服务器将始终阻塞,因为您正在
ReadInt32()
ing三次。您确定其他int数据包是由您的服务器发送的吗


其次,我不会使用ZlibStream直接从网络套接字读取数据。我从网络流中读取原始数据,对其进行缓冲,并在数据在缓冲区中解压时触发另一个方法。。。 在psuedocode中:

byte[] compressedDataBuffer
bool canReadFromBuffer = false;
ASYNC:
    while(true):
        get current network stream, see if there's data
        if it has data:
            add networkStream's current data to compressedDataBuffer
            lock:
                if compressedDataBuffer has new data/has enough data
                    canReadFromBuffer = true
                else
                    canReadFromBuffer = false
        else:
            sleep(0); //yield cycles
SYNC:
    while(true):
        if canReadFromBuffer:
            create a memory stream of compressedDataBuffer
            create a zlibstream around that memory stream
            perform operations on the zlibstream that are required.

如果你能发布更多的代码,这会有所帮助。这里使用阻塞读取,考虑重构代码使用异步/等待模式和异步读取(即,RealTime32 AsiNC)。异步读取不会解决我的问题。我指的是读写两个端,所以没有块。不是实际的套接字本身。我看不出异步调用读和写是如何解决任何问题的。除非你误解了我的问题如果你想责怪
ZlibStream
,试着用(比如)MemoryStream替换它以进行调试,看看问题是否消失。所有数据包都在流中被压缩和刷新,如下所示:
78 5E 00 FF 00 00 FF 00 FF 00 FF 00 FF 00 FF 00 FF 00 FF 00 FF 00 FF 00 FF 00 FF 00 FF 00 FF 00 FF 00 FF 00 FF 00 FF 00 FF 00 FF 00 FF 00 FF 00 FF 00 FF 00 FF等…
为什么这还不够,对
ZlibStream
调用
Flush
是否会完成当前压缩缓冲区并将压缩数据发送到原始输出流?@Angelo,您是否将ZlibStream上的
FlushMode
设置为
FlushType.Sync
FlushType.Full
?我将其设置为
FlushType.Full
@AngeloGeels,你试过关闭小溪而不是冲洗吗?有帮助吗?