我有一个简单的文件服务器\客户端应用程序我用c#编写。但我经常遇到我的流将两个不同的读写写入单个缓冲区的问题。我有一个同步流,仍然没有帮助。有什么建议?谢谢!
System.Threading.Thread.Sleep(25);
receive_fspos = new byte[30];
int bytesread = stream_1.Read(receive_fspos, 0, receive_fspos.Length);//this is where it gets combined
if (bytesread == 0)
{
finished = true;
System.Threading.Thread.Sleep(25);
}
string string_1 = utf.GetString(receive_fspos).TrimEnd(new char[] { (char)0 });
int fsposition = (int)Convert.ToInt64(string_1);
bytestosend = fsposition;
filestream.Position = fsposition;
byte[] buffer_1 = new byte[bufsize];
int bytesreadfromfs = filestream.Read(buffer_1, 0, buffer_1.Length);
stream_1.Write(buffer_1, 0, buffer_1.Length);
Console.Write("\rSent " + fsposition + " / " + length + " bytes");
finished = true;
答案 0 :(得分:3)
如果您不完全理解,我建议不要编写自己的流方法。
您遇到的问题是因为传入的数据是一个字节流,无法让您知道消息的长度字节数。
在下面的代码中,您声明要读取流的“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);
}
答案 1 :(得分:0)
让它工作,代码> 30000个字符: 它有点乱,但嘿,它的功能。