0

I'm using a NamedPipeStream, client and server, I'm sending data from client to server, the data is a serialize object which include binary data.

When the server side receive the data, I try to deserialize the data I received: TransmitDataCommand dataR= JsonConvert.DeserializeObject(e.Message));

I tried to save the data in base64 string instead of byte[] but still not work!!

But I get an exception:

"Unterminated string. Expected delimiter: ". Path 'Data', line 1, position 1024."

Why? how to solve this :(?

Send from client: write(lTransmitDataCommand.Message())

The pipe read the data: OnReceivedMessage(this,new ReceivedMessageEventArgs(Encoding.ASCII.GetString(message)));

and try: JsonConvert.DeserializeObject(e.Message)); // wher the exception happen!

The Object:

[Serializable]
public abstract class AgentConnectorAbstractCommand
{
    public virtual eAGENTCONNECTOR_CommandOpcode Opcode { get; set; }
    public virtual void Dispose()
    {
        return;
    }
    public abstract string Message();
}

public enum eComandType{
    /// <summary>
    /// This command is from client to Agent
    /// </summary>
    eCLIENT2AGENT_CMD=0,
    /// <summary>
    /// This command is from agent to client
    /// </summary>
    eAGENT2CLIENT_CMD=1,
    /// <summary>
    /// This command is from client to Agent
    /// </summary>
    eRESPONSE_CMD=2,
}
[Serializable]
public class TransmitDataCommand : AgentConnectorAbstractCommand
{
    public TransmitDataCommand()
    {
        IsBinary = false;
    }
    private eAGENTCONNECTOR_CommandOpcode _Opcode = eAGENTCONNECTOR_CommandOpcode.eTRANSMITDATA;
    public override eAGENTCONNECTOR_CommandOpcode Opcode { get { return _Opcode; } }

    /// <summary>
    /// Define what is the type of the data (is it command or response)
    /// </summary>
    public eComandType ComandType { get; set; }

    /// <summary>
    /// indicate if the data is byte array or text
    /// </summary>
    public bool IsBinary { get; set; }

    /// <summary>
    /// Hold the byte data
    /// </summary>
    public byte[] Data
    {
        get
        {
            if ((DataTxT == null)||(IsBinary==false))
            {
                return null;
            }
            return Convert.FromBase64String(DataTxT);
        }
        set
        {
            if (value == null)
            {
                IsBinary = false;
                this.DataTxT = null;
                return;
            }
            try
            {
                IsBinary = true;
                //keep a clone of the image to protect from any changes outside!!!
                this.DataTxT = Convert.ToBase64String(value);
            }
            catch { }
        }
    }

    /// <summary>
    /// Hold the string data
    /// </summary>
    private string lTextData = null;
    public string DataTxT
    {
        get
        {
            return lTextData;
        }
        set
        {
            this.lTextData = value;
        }
    }

    public override void Dispose()
    {
        lTextData= null;
        GC.Collect();
    }
    /// <summary>
    /// Return serialized object
    /// </summary>
    public override string Message()
    {
        TransmitDataCommand l = new TransmitDataCommand
        {
            Opcode = this._Opcode,
            ComandType = this.ComandType,
            DataTxT = this.DataTxT,
            IsBinary = this.IsBinary
        };
        return JsonConvert.SerializeObject(l);
    }
    }
Joseph
  • 1,716
  • 3
  • 24
  • 42

2 Answers2

0

You have a lot of design issues in your classes. Why you don't serialize current instance instead of creating a new one? Anyway, add JsonIgnoreAttribute to the Data property.

Hamlet Hakobyan
  • 32,965
  • 6
  • 52
  • 68
  • Thanks @Hamlet!, It was Serialize(this), I had an exception, I try change it to verify it is not the issue, seems like forget to return it back (I change it back). Anyway adding the "JsonIgnoreAttribute" to the Data property, cause the exception: Unterminated string. Expected delimiter: ". Path 'DataTxT', line 1, position 1024. – Joseph Aug 10 '15 at 06:40
  • BTW, I see that in the low level implementation of my PIPE, in the ReadFromPipe , after byte[] msg = ReadMessage(Pipe); I encode the data : Encoding.ASCII.GetString(message)), is this could harm the data? – Joseph Aug 10 '15 at 06:43
0

The problem was in the way I sent the data, I was using StreamWriter - when sending a long enough message, the result will be a multiple Write calls on the pipe stream => multiple separate message for the data.

So to send a whole message as a single message, we must use a single Write call using the Pipe.write itself. For example:

var data = Encoding.ASCII.GetBytes(JsonString);
Pipe.Write(data, 0, data.Length);

and not StreamWriter.Writelen(JsonString)

for more info, thanks to Luaan, see: NamedPipeServerStream receive MAX=1024 bytes, why?

Community
  • 1
  • 1
Joseph
  • 1,716
  • 3
  • 24
  • 42