我们在编写与Socket有关的应用程序时,在发送软为复杂的数据时,可能我们最常做的是把各个部分的数据转换为字符串,然后将这些字符串用一个分隔符连接起来进行发送。不过,不知道你有没有想过这样做还是有问题的。
比如,我用#来分隔各个字符串,在根据客户端输入的内容到服务器端进行查找,然后返回结果,万一用户输入的查找关键字中就包含#,那么就会影响我们对字符串进行分割了。
不知道各位有没有想过,把序列化和反序列化的技术也用到socket上?先定义一个封装数据的类,发送前将该类的对象序列化,然后发送;接收时,先接收字节流,然后再反序列化,得到某个对象。
这样一来是不是比单单发送字符串好多了。
下面我举的这个例子,服务器端用WPF开发,客户端是Windows Store App,当然我这里只是举例,其实这可以用于所有类型的应用程序,包括Windows Phone应用,原理是不变的。
一、服务器端
首先我们定义一个用于封装数据的类,这里就以一个产品信息类做演示,这个类在服务器端和客户端都要定义一遍,这样才方便序列化和反序列化,你也可以特立写到一个类库中,然后服务器端和客户端都引用该类库。
[DataContract(Name = "product")]
public class Product
{
/// <summary>
/// 产品编号
/// </summary>
[DataMember(Name = "product_no")]
public string ProductNo { get; set; }
/// <summary>
/// 产品名称
/// </summary>
[DataMember(Name = "product_name")]
public string ProductName { get; set; }
/// <summary>
/// 产品单价
/// </summary>
[DataMember(Name = "product_price")]
public decimal ProductPrice { get; set; }
}
WPF窗口的XAML
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0" Margin="11">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<TextBlock Text="产品编号:" Grid.Column="0" Grid.Row="0" Style="{DynamicResource tbLabel}"/>
<TextBlock Text="产品名称:" Grid.Column=