i have done a bit of reading in client/server programming in c#. i am familiar enough with this process to ask the following question:
how do i transmit structure objects through tcp/ip instead of just strings?
my app is a networked game with chat capabilities. so instead of just transmitting text, i would like to imploy a data structure or class structure that will have two fields: i. packet type ii. the data for the packet type
and i would transmit this when needed during the execution of the application, and decode the data object at the receiving end and place it where it belongs.
im not looking for code, just some ideas and search statements i can feed to google so i will; have a better understanding.
ive read about serialisation/de serialisation, is that he way to go?
thanks.
i have checked the posts that showed up as related topics but would still like further guidence.
C programming language is a machine-independent programming language that is mainly used to create many types of applications and operating systems such as Windows, and other complicated programs such as the Oracle database, Git, Python interpreter, and games and is considered a programming foundation in the process of ...
In the real sense it has no meaning or full form. It was developed by Dennis Ritchie and Ken Thompson at AT&T bell Lab. First, they used to call it as B language then later they made some improvement into it and renamed it as C and its superscript as C++ which was invented by Dr.
C is a general-purpose language that most programmers learn before moving on to more complex languages. From Unix and Windows to Tic Tac Toe and Photoshop, several of the most commonly used applications today have been built on C. It is easy to learn because: A simple syntax with only 32 keywords.
C is more difficult to learn than JavaScript, but it's a valuable skill to have because most programming languages are actually implemented in C. This is because C is a “machine-level” language. So learning it will teach you how a computer works and will actually make learning new languages in the future easier.
Ultimately yes: you are talking about serialization. This can take many forms, especially in .NET, but ultimately you need to pick between:
My.Namespace.FooBar
instance). This makes it really easy to get working, but rarely works between different platforms (and often not between versions) - and all that type information can be verboseManual serializer approaches include (just mentioning the "serializer" keyword): TextWriter
, XmlWriter
, IXmlSerializable
, BinaryWriter
, ISerializable
. You don't want to do that...
Focusing more on the automatic serializers:
| Contract | Metadata
===============+========================+===========================
Text | XmlSerializer | SoapFormatter
| DataContractSerializer | NetDataContractSerializer
| Json.NET |
---------------+------------------------+---------------------------
Binary | protobuf-net | BinaryFormatter
Since you are talking raw streams, my preference would be a binary contract-based serializer - but then, I wrote protobuf-net, so I may be biased ;-p
For comparison with common RPC stacks:
BinaryFormatter
XmlSerializer
DataContractSerializer
or NetDataContractSerializer
, and sometimes XmlSerializer
(it can also be configured to use, for example, protobuf-net)I can happily write an example of using protobuf-net on a stream to represent different messages of different types, but a simple example of socket processing using protobuf-net is in one of the sample projects (here, in fact)
If you don't need the richness of serialization - if you just wanna write a structure to a byte array, consider the Marshal class.
For example, consider a tar app in C#. The tar format is based on 512-byte blocks, and the first block in a series has a regular structure. Ideally the app wants to just blitt the data from the disk file, right into a structure. The Marshal.PtrToStructure method does this. Here's the structure.
[StructLayout(LayoutKind.Sequential, Size=512)]
internal struct HeaderBlock
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 100)]
public byte[] name; // name of file.
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public byte[] mode; // file mode
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public byte[] uid; // owner user ID
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public byte[] gid; // owner group ID
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)]
public byte[] size; // length of file in bytes
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)]
public byte[] mtime; // modify time of file
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public byte[] chksum; // checksum for header
// ... more like that... up to 512 bytes.
Then here's a generic class that does the blitting.
internal class RawSerializer<T>
{
public T RawDeserialize( byte[] rawData )
{
return RawDeserialize( rawData , 0 );
}
public T RawDeserialize( byte[] rawData , int position )
{
int rawsize = Marshal.SizeOf( typeof(T) );
if( rawsize > rawData.Length )
return default(T);
IntPtr buffer = Marshal.AllocHGlobal( rawsize );
Marshal.Copy( rawData, position, buffer, rawsize );
T obj = (T) Marshal.PtrToStructure( buffer, typeof(T) );
Marshal.FreeHGlobal( buffer );
return obj;
}
public byte[] RawSerialize( T item )
{
int rawSize = Marshal.SizeOf( typeof(T) );
IntPtr buffer = Marshal.AllocHGlobal( rawSize );
Marshal.StructureToPtr( item, buffer, false );
byte[] rawData = new byte[ rawSize ];
Marshal.Copy( buffer, rawData, 0, rawSize );
Marshal.FreeHGlobal( buffer );
return rawData;
}
}
You can use that class with any structure. You have to use LayoutKind.Sequential and restrict yourself to blittable types (basically primitives and arrays of same) to use this approach. It's fast and efficient, in terms of code and performance and memory, but it's a little restricted in how it can be used.
Once you have the byte array, you can transmit it over a NetworkStream or etc, and then de-serialize using the same class on the other end.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With