0

I have a black box. I connect to it via TCP. The black box helpfully provides an Interface Control Document which tells me the format of the data I'll be recieving. It may be something like:

  • Bytes 0-3 UINT32: id of thing
  • Bytes 4-8 UINT32: type of thing
  • [and, you, know, like 100 other elements of varying data types]

In C#, how can I get the data I have taken off the TCP socket and get it into the format I know it to be in?

In C, I could just memcpy from a buffer into a struct. Or I could recast the buffer to become the struct I know it to be. I've been casting around for how to best do this in C# and so far find the answers to be somewhere between baffling and way more complicated than I was expecting (C# lacks typedefs and seems to frown on structs in general). So far my best attempt is to make the message as a class:

class MessageThing
{
    public uint thingId;
    public uint thingType;
    [...insert loads of other data fields here...]
}

...and then painfully use BitConverter.ToUint32(buffer, offset) to copy, piece by piece, into my class, from my message buffer. Surely there is a more efficient way of parsing than this. (I found this sort of thing to be super easy in Python and Java, and actually easy enough in C, so I'm clearly missing something for C#?)

JamieB
  • 703
  • 1
  • 6
  • 17
  • None of the linked answers result in a class object. They all assume I want it in a struct, and therefore are less than ideal answers to my question. Do I really have no choice? – JamieB Feb 10 '23 at 20:28
  • The following may be of interest: https://www.codeproject.com/Articles/5264831/How-to-Send-Inputs-using-Csharp – Tu deschizi eu inchid Feb 10 '23 at 20:32
  • If you're going to write in abstractions, you're answers/responses are going to most likely be abstract. You may consider providing a [minimal, reproducible example](https://stackoverflow.com/help/minimal-reproducible-example) which others can use to re-create the issue that you're facing (ie: the code should compile). Also, include sample data that can be used for testing (or a means of generating sample data). – Tu deschizi eu inchid Feb 10 '23 at 20:36
  • @user09938 It's really a question of not knowing which language features may be available to do what I want, with the answer possibly being "they do not exist". In Python, you just use struct.unpack to get the data out in the format specified. C# seems to rely on Marshal to manhandle data into structs and I guess that's just the only way to do it. (The structs also seem to require some amount of "Mashal" and "unsafe"... it's....icky.) – JamieB Feb 10 '23 at 20:41
  • Unfortunately, I don't know Python. When attempting to write something in a different language you may find it best to not try to relive your glory days whether they be in Python, Java, C, etc... and learn how to do it in the language you're attempting to program in. As far as _not knowing which language features may be available to do what I want_: Perhaps I'm not as experienced in network programming as you, but I only vaguely understand what you're trying to accomplish. – Tu deschizi eu inchid Feb 10 '23 at 21:47
  • You may consider getting some inspiration by going back to the basics - perhaps some [pseudo-code](https://stackoverflow.com/a/65030908/10024425) – Tu deschizi eu inchid Feb 10 '23 at 21:47
  • You must use a struct with the layout attribute on each field. Then you can pin the memory and create a pointer in an unsafe context. –  Feb 10 '23 at 22:15

0 Answers0