Несколько вопросов по сериализации / десериализации - PullRequest
0 голосов
/ 26 октября 2019

Несколько лет назад я написал небольшое TCP-приложение для торговли акциями, изучая Socket, и в то время я не знал о Json или двоичной сериализации / десериализации и следуя некоторым статьям / ответам с этого сайта или где-то еще, ясделал Struct вот так для передачи между клиентами и сервером:

[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct TradeItem
{
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 15)]
    public string Status;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
    public string EndPoint;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 10)]
    public string ItemName;      
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 5)]
    public string Mode;
    public int Quantity;
    public double Price;
    public int PartyCode;
    public int OrderNo;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
    public string BrokerBought;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
    public string BrokerSold;
    public int PartySold;
    public int PartyBought;
    public int QtyTraded;
    public double PriceTraded;
}

и для преобразования его в byte[] и возврата к Struct, я бы использовал эти вспомогательные методы:

public byte[] Pack(TradeItem ti)
{
    int size = Marshal.SizeOf(ti);
    byte[] array = new byte[size];
    IntPtr ptr = Marshal.AllocHGlobal(size);
    Marshal.StructureToPtr(ti, ptr, false);
    Marshal.Copy(ptr, array, 0, size);
    Marshal.FreeHGlobal(ptr);
    return array;
}

public TradeItem UnPack(byte[] arr)
{
    TradeItem ti = new TradeItem();
    int size = Marshal.SizeOf(ti);
    IntPtr ptr = Marshal.AllocHGlobal(size);
    Marshal.Copy(arr, 0, ptr, size);
    ti = (TradeItem)Marshal.PtrToStructure(ptr, ti.GetType());
    Marshal.FreeHGlobal(ptr);
    return ti;
}

со всем этим я бы отправлял по одному предмету за раз! Я до сих пор не знаю, как бороться с произвольным размером List<TradeItem >! Если кто-то знает, как поступить с List<TradeItem >, было бы неплохо это знать. Теперь я могу отправлять туда и обратно по одному TradeItem и / или List<TradeItem> с Newtonsoft.Json или BinaryFormatter. Есть ли какая-то польза от использования таких маршалинговых / криптических атрибутов по сравнению с простой сериализацией / десериализацией с Newtonsoft.Json или BinaryFormatter? По моей локальной сети я всегда получаю то, что отправляю с этими:

//send
var data = new List<TradeItem>;
.
.
.
byte[] array = null;
using(var stream = new MemoryStream())
{
    var formatter = new BinaryFormatter();
    formatter.Serialize(stream, data);
    array = stream.ToArray();           
}

//receive
var formatter = new BinaryFormatter();
var list = formatter.Deserialize(new MemoryStream(e.Buffer)) as List<TradeItem>;

или

//send
var array = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(data));

//receive
var json = Encoding.UTF8.GetString(e.Buffer);
var list = JsonConvert.DeserializeObject<List<TradeItem>>(json);

Мне просто нужно создать достаточно большое byte[]! Могу ли я получить то, что отправляю, используя эти BinaryFormatter и JsonConvert при условии, что у меня достаточно большой byte[]?

...