0

I am stuck with the following problem: I am communicating with another application using TcpClients/Streams.

This application needs input parameters passed to it, encoded in a special way (something along first byte: parameter type identifier, next 4 bytes: content length; next length bytes: content).

The application processes the input and gives me the output back in the same format. My problem is that I usually don't know the exact order of different return values. The application could return nothing, one int, 5 ints, 2ints and an IntArray...

EDIT: To clarify this, I can not change the underlying protocol or the source code of the application I am communicating with!

The problem is that I want to be able to use the params as if they were "native" C# objects. What I tried achieving is the following approach:

https://dotnetfiddle.net/ZjbUix

I am not really sure whether this is a good idea. Maybe it would be a better alternative to have a EncodingStream(NetworkStream) with Write() methods for all possible parameter types, and a DecodingStream(NetworkStream) with GetInt(), GetIntArray() etc. methods. This would, however, more or less disregard the type identifier and could only be prevented with throwing an Exception along "Attempted to read an Int value but found Int Array parameter type".

EDIT: I implemented this version here: https://dotnetfiddle.net/8WVXPz

Another requirement is that it should be possible to easily add new parameter types while at best detecting errors at compile-time. Additionally, I'd prefer a non-reflection solution.

Maybe someone can make up an even better architecture to support this?

Zahlii
  • 818
  • 1
  • 7
  • 17
  • [This answer](http://stackoverflow.com/a/21510978/932418) seems like what you are after – Eser Aug 11 '15 at 11:17
  • This would still leave me with the problem that I don't know the result parameter's order, thus it might happen that `ReadObject` attempts to read an `int[]` array instead. – Zahlii Aug 11 '15 at 11:21
  • Zahlii, Don't send parameters one by one. Create a , for example, Command class, put your methodname and all parameters in it and send as one object. `public class Command { public string Cmd { set; get; } public List parameters { set; get; } }` or maybe paramters as key-value pairs `public class Command { public string Cmd { set; get; } public Dictionary parameters { set; get; } }` – Eser Aug 11 '15 at 11:23
  • The simplest method is to send a CSV line where parameters are separated by commas. Use string.Join(",", string[]) – jdweng Aug 11 '15 at 12:24
  • @jdweng If one of the parameter is a complex type (like Employee) than csv can be a problem. – Eser Aug 11 '15 at 12:36
  • I should maybe clarify that I can't simply edit the protocol, or the other application. That is, I can't simply decide to send CSV, but have to stick to the appropriate byte encoding. – Zahlii Aug 11 '15 at 12:44
  • You have an application level protocol. The parameter must meet you requirements. I wasn't clear how much leeway you had it sending the parameters. If it is true c language parameter list than you parameters are pushed on a stack in reverse order with last parameter at bottom of stack and first parameter at top of stack. This doesn't make a lot of sense if you are passing parameters as pointers across a Comm interface or trying to send object like employee. I would double check your requirements and make sure you are interpreting them correctly. – jdweng Aug 11 '15 at 13:38

0 Answers0