在使用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。