C# 从没有数据时stream.Read()等待的字符串创建空流
我试图将从C# 从没有数据时stream.Read()等待的字符串创建空流,c#,string,stream,tcpclient,C#,String,Stream,Tcpclient,我试图将从TcpClient.GetStream()获取的流替换为从字符串创建的流 我正在使用以下方法创建所述流: public Stream GenerateStreamFromString(string s) { MemoryStream stream = new MemoryStream(); StreamWriter writer = new StreamWriter(stream); writer.Write(s); writer.Flush();
TcpClient.GetStream()
获取的流替换为从字符串创建的流
我正在使用以下方法创建所述流:
public Stream GenerateStreamFromString(string s)
{
MemoryStream stream = new MemoryStream();
StreamWriter writer = new StreamWriter(stream);
writer.Write(s);
writer.Flush();
stream.Position = 0;
return stream;
}
但是,此流是通过使用我不想更改的库中的某个地方的stream.read()
来读取的。问题是我用空字符串创建这个流,因为对象需要一个流来启动,通常在使用TcpClient
流时,它会在stream.Read()
处停止,直到它有东西要读,但不是用我从字符串创建的流
因此,我的问题是,如何创建一个空流,以便以后可以从字符串向其中添加数据?在内部使用
BlockingCollection
作为队列,您可以编写如下内容:
public class WatitingStream : Stream
{
private BlockingCollection<byte[]> Packets = new BlockingCollection<byte[]>();
private byte[] IncompletePacket;
private int IncompletePacketOffset;
public WatitingStream()
{
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
Packets.CompleteAdding();
}
base.Dispose(disposing);
}
public override bool CanRead
{
get { return Packets.IsCompleted; }
}
public override bool CanSeek
{
get { return false; }
}
public override bool CanWrite
{
get { return Packets.IsAddingCompleted; }
}
public override void Flush()
{
}
public override long Length
{
get
{
throw new NotSupportedException();
}
}
public override long Position
{
get
{
throw new NotSupportedException();
}
set
{
throw new NotSupportedException();
}
}
public override int Read(byte[] buffer, int offset, int count)
{
if (count == 0)
{
return 0;
}
byte[] packet;
int packetOffset;
if (IncompletePacket != null)
{
packet = IncompletePacket;
packetOffset = IncompletePacketOffset;
}
else
{
if (Packets.IsCompleted)
{
return 0;
}
packet = Packets.Take();
packetOffset = 0;
}
int read = Math.Min(packet.Length - packetOffset, count);
Buffer.BlockCopy(packet, packetOffset, buffer, offset, read);
packetOffset += read;
if (packetOffset < packet.Length)
{
IncompletePacket = packet;
IncompletePacketOffset = packetOffset;
}
else
{
IncompletePacket = null;
IncompletePacketOffset = 0;
}
return read;
}
public override long Seek(long offset, SeekOrigin origin)
{
throw new NotSupportedException();
}
public override void SetLength(long value)
{
throw new NotSupportedException();
}
public override void Write(byte[] buffer, int offset, int count)
{
if (count == 0)
{
return;
}
byte[] packet = new byte[count];
Buffer.BlockCopy(buffer, offset, packet, 0, count);
Packets.Add(packet);
}
}
public class waitingstream:Stream
{
private BlockingCollection数据包=新建BlockingCollection();
专用字节[]不完整数据包;
私有整数不完全packetoffset;
公共水流()
{
}
受保护的覆盖无效处置(布尔处置)
{
如果(处置)
{
Packets.CompleteAdding();
}
基地。处置(处置);
}
公共覆盖布尔可读取
{
获取{return Packets.IsCompleted;}
}
公共覆盖布尔搜索
{
获取{return false;}
}
公共覆盖布尔可写
{
获取{return Packets.IsAddingCompleted;}
}
公共覆盖无效刷新()
{
}
公共覆盖长长度
{
得到
{
抛出新的NotSupportedException();
}
}
公众优先多头仓位
{
得到
{
抛出新的NotSupportedException();
}
设置
{
抛出新的NotSupportedException();
}
}
公共重写整型读取(字节[]缓冲区、整型偏移量、整型计数)
{
如果(计数=0)
{
返回0;
}
字节[]数据包;
int-packetOffset;
if(不完整数据包!=null)
{
数据包=不完全数据包;
packetOffset=不完全packetOffset;
}
其他的
{
如果(数据包已完成)
{
返回0;
}
packet=Packets.Take();
packetOffset=0;
}
int read=Math.Min(packet.Length-packetOffset,count);
块复制(数据包、包偏移、缓冲区、偏移、读取);
packetOffset+=读取;
if(packetOffset
您将其用作普通流。写入操作不阻塞。读取
块
必须做出一些决定:这个流是基于“数据包”的。它不会写入
零长度数据包,而读取
将返回一个数据包的数据。读取
不会在下一个数据包上继续。如果在读取
后数据包中仍有数据,则该数据将保存以供下次读取
。Dispose()
将停止Write
(因此,如果“客户机”在“服务器”之前执行Dispose()
,则如果服务器尝试执行Write
,则会出现异常)。如果“服务器”先执行Dispose()
,则“客户端”可以完成对仍然存在的数据包的读取。显然,可以(很容易)将此类分为两类(一类是服务器
和一类是客户端
),其中服务器
保存BlockingCollection
,客户端引用“服务器”。这将解决“Dispose()
”异常/问题(但会使代码大小加倍:-)这怎么不只是不信者的重复呢?@Damien\u因为现在另一个问题已被删除:-)@Damien\u不信者这个问题不同,因为它的措辞更好,更紧凑,它实际上实现了我想要的:生成正确的答案,而不是我之前的问题,我已经删除了,因为我意识到这是一个骗局。但这就是选择的目的-如果你没有得到你想要的答案,你应该编辑你的问题来改进它,而不是发布一个新的问题。是的@Damien_,不信者,我用不同的问题尝试过,但是由于问题的数量太多,旧的问题被新的问题淹没了,所以我想尝试一下,它很有魅力。这是不允许的吗?