如果您不完全了解它,我不会建议编写自己的流方法。
您遇到的问题是,因为输入的数据是不给你知道在长度消息是多少字节的方式字节流。
在下面你的代码,说明你想读流的“receive_fspos.Length”字节。由于“receive_fspos.Length”是30,将被读取的字节的量将是在任何地方从0到30。
如果只有15已经由连接接收的字节。它会给你15个字节。如果消息长度为20个字节。然后,该消息现在分成不同的部分。
如果所述第一消息是4个字节,所述第二消息是12个字节。现在你在结尾处有2条消息和一组16个空白字节。更糟糕的是,这16个“空白”字节可能是第三条消息进入流的开始。
如果该消息是50个字节长。那么你只会收到一半的消息。现在您需要将读取的字节添加到单独的缓冲区中。再次从流中读取。然后重复此操作,直到确定您已阅读完成整个消息所需的确切字节数。然后将所有读取字节连接回单个字节[]。
receive_fspos = new byte[30];
int bytesread = stream_1.Read(receive_fspos, 0, receive_fspos.Length);//this is where it gets combined
不是滚动您自己的循环请使用BCL方法。它听起来像你正在使用字符串,所以这将是首选的方法..我会建议如下。
using(NetworkStream networkStream = tcpClient.GetStream())
using(StreamReader streamReader = new StreamReader(networkStream))
using(StreamWriter streamWriter = new StreamWriter(networkStream))
{
networkStream.ReadTimeout = timeout; //Set a timeout to stop the stream from reading indefinately
//To receive a string
string incomingString = stream.ReadLine();
//To send a string
stream.WriteLine(messageToSend);
stream.Flush();
}
您的答案阐明了您正在尝试发送文件。为此我建议发送一个字节数组[]。使用这种方法,你可以发送任何可以序列化的东西。这包括一个文件。请注意,文件的大小是有限的,因为它必须保存在内存中。为了写一个更大的文件,你会希望将数据保存块,因为它是被流
//Please note that if the file size is large enough. It may be preferred to use a stream instead of holding the entire file in memory.
byte[] fileAsBytes = File.ReadAllBytes(fileName);
using(NetworkStream networkStream = tcpClient.GetStream())
using(BinaryReader binaryReader = new BinaryReader(networkStream))
using(BinaryWriter binaryWriter = new BinaryWriter(networkStream))
{
networkStream.ReadTimeout = timeout; //Set a timeout to stop the stream from reading indefinately
//To receive a byte array
int incomingBytesLength = BinaryReader.ReadInt32(); //The header is 4 bytes that lets us know how large the incoming byte[] is.
byte[] incomingBytes = BinaryReader.ReadBytes(incomingBytesLength);
//To send a byte array
BinaryWriter.Write(fileAsBytes.Length); //Send a header of 4 bytes that lets the listener know how large the incoming byte[] is.
BinaryWriter.Write(fileAsBytes);
}
你是说,例如,你写的每一个10个字节两条消息流,并在另一端接收20个字节?这就是为什么它被称为流。一端的字节以相同的顺序出来,没有重复或丢失。没有一个实体的概念大于一个字节,即_message_或_record_。读取中接收的字节数取决于整个网络的缓冲。如果您总共写入100个字节,则可以从第一次读取中获得43个字节,然后从下一个字节中获得56个字节,然后获得单个字节。 – HABO 2013-02-23 03:56:18
不完全。我已经将每个读取的长度设置为哦,比方说30个字节,每个消息实际上是8个字节,它在stream.read()方法的一次调用中写入服务器的两个stream.write()调用缓冲区。它不应该这样做,它应该将8字节消息和22个空白字节写入一个30字节缓冲区。对? – user2038443 2013-02-23 04:04:56
对不起,但是一次读取将检索所有可用数据,直到缓冲区的大小。缓冲区中的任何剩余字节都不会受到影响,即被清除。如果你想将字节流解释为消息,那么_you_需要创建一种方法来确定每条消息的边界。我已经使用了一个头,其中前两个或四个字节包含消息的长度。额外的头域可能包含消息类型,子类型,ID,...。由于字节以任意大小的组接收,因此您必须准备好重新组合来自碎片的消息。即使长度字段可以分散! – HABO 2013-02-23 04:13:01