如果您不完全瞭解它,我不會建議編寫自己的流方法。
您遇到的問題是,因爲輸入的數據是不給你知道在長度消息是多少字節的方式字節流。
在下面你的代碼,說明你想讀流的「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