Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.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
C# 从没有数据时stream.Read()等待的字符串创建空流_C#_String_Stream_Tcpclient - Fatal编程技术网

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_,不信者,我用不同的问题尝试过,但是由于问题的数量太多,旧的问题被新的问题淹没了,所以我想尝试一下,它很有魅力。这是不允许的吗?