C#網路程式設計,傳輸資料的3種方式
阿新 • • 發佈:2019-01-30
在使用socket繫結networkstream進行網路傳輸時,傳輸的形式都是以位元組陣列(byte[])進行的。意味著進行讀取時都是以位元組陣列的形式進行。
所以當進行網路通訊傳輸資料時,我們可以使用一下3種方式。
1.定義所有的資訊為同一個型別資料,這樣在進行型別轉換時最方便。
但是缺點為:由於將所有的型別聚集在一起進行傳輸,接受時需要進行資訊的切割,以獲得所需資訊。無法描述複雜的組合資料型別。
例如string型別程式碼:
public void Send_Date(string str) //傳送資料 { TcpClient Ts = Ret_Client(); NetworkStream nws = Ts.GetStream(); byte[] byts = TypeChange.StringtoBytes(str); nws.Write(byts, 0, byts.Length); } public string Get_Data() //獲取單獨的資料項 { string str = null; int index = 0; while(!IM) { Receive_Date(imageLength); return null; } if (Buffer.Length != 0) { string Bf = Buffer.ToString(); index = Bf.IndexOf('#'); //預設設定#為不同資料之間的分隔符 if (index == -1) //如果Buffer中存在分隔符,則將第一部分加入str,第二部分存入Buffer { str += Bf; Buffer.Clear(); } else { str += Bf.Substring(0, index); string BB = Bf.Substring(index + 1, Bf.Length-index-1); Buffer.Clear(); Buffer.Append(BB); if (str.Equals("!")) { imageLength = Convert.ToInt32(Get_Data()); IM = false; } } return str; } else { Thread.Sleep(1000); Receive_Date(); return Get_Data(); } } private void Receive_Date() //獲取客戶端傳入的資料 { TcpClient Ts = Ret_Client(); NetworkStream nws = Ts.GetStream(); while (nws.DataAvailable) { CleanByteArray(Data_byte, Data_Length); nws.Read(Data_byte, 0, Data_Length); this.Buffer.Append(TypeChange.BytesToString(Data_byte, Data_Length)); } } private void Receive_Date(int i) //獲取客戶端傳入的資料 { TcpClient Ts = Ret_Client(); NetworkStream nws = Ts.GetStream(); ImageByte = new byte[i]; int index = 0; if (Buffer.Length != 0) { string str = Buffer.ToString(); Buffer.Clear(); byte[] by = TypeChange.StringtoBytes(str); foreach (byte n in by) { ImageByte[index] = n; index++; } } int offset = index; while (offset<ImageByte.Length) { if (ImageByte.Length -offset >Data_Length) { nws.Read(ImageByte, offset, Data_Length); } else { nws.Read(ImageByte, offset,ImageByte.Length - offset); } IM = true; offset +=Data_Length; Send_Date("收到"); } } private void CleanByteArray(byte[] Data_byte, int Length) { for (int index = 0; index < Length; index++) { Data_byte[index] = 0; } }
2.定義一個類或結構體型別,將所有簡單型別包含於複合型別中。這樣可以描述複雜的資料型別。
但是缺點為:當定義一個結構體或類型別後,但是我們只有在特殊情況下需要傳輸所有的結構體或類中的資訊。一般情況下只需傳輸幾個簡單的資訊。這樣在傳輸過程中產生了浪費,對轉換的過程中也有不利的影響。
例如類型別程式碼:
public void Send_Date(object obj) { TcpClient Ts = Ret_Client(); //獲取TCP連線 NetworkStream nws = Ts.GetStream(); //獲取網路流 System.IO.MemoryStream memStream = TypeChange.SerializeBinary(obj); byte[] byt = new byte[memStream.Length]; memStream.Read(byt, 0, byt.Length); nws.Write(byt, 0, byt.Length); } public object Receive_Date() { TcpClient Ts = Ret_Client(); NetworkStream nws = Ts.GetStream(); while (nws.DataAvailable) { byte[] byt = new byte[nws.Length]; //讀取資料 nws.Read(byt, 0, byt.Length); memStream.Write(byt, 0, byt.Length); } return TypeChange.DeSerializeBinary(memStream); }
3.定義一個Dictionary<Tkey,Tvalue>型別,這樣就解決了上面兩種方式存在的缺點。由於每一個Tkey對應一個不同型別的Tvalue,這樣在不同的情況下可以產生不同的資料資訊進行傳輸。
例如Dictionary<int,object>型別程式碼:
public void Send_Date(object obj) { TcpClient Ts = Ret_Client(); //獲取TCP連線 NetworkStream nws = Ts.GetStream(); //獲取網路流 System.IO.MemoryStream memStream = TypeChange.SerializeBinary(obj); byte[] byt = new byte[memStream.Length]; memStream.Read(byt, 0, byt.Length); nws.Write(byt, 0, byt.Length); } public object Receive_Date() { TcpClient Ts = Ret_Client(); NetworkStream nws = Ts.GetStream(); while (nws.DataAvailable) { byte[] byt = new byte[nws.Length]; //讀取資料 nws.Read(byt, 0, byt.Length); memStream.Write(byt, 0, byt.Length); } return TypeChange.DeSerializeBinary(memStream); }
第二種和第三種方式的底層程式碼相同,但是傳入的實參型別不同。
另外一種流行的傳輸方式JSON。