❔ Are strings the best way for Server-Client UDP communication?
Hi I'm developing a server-client udp communication system using System.Net ( with classes like UdpClient, IPEndPoint etc. )
Right now my endpoints communicate through strings, example with a stupid request:
1) Server creates a string "Are you hungry?" converts it to bytes and sends it to client through UDP
2) Client receives the bytes, converts them to string, compares the string in a switch statement with a set of predefined strings.
3) Case "Are you hungry?" is met, logic runs and client creates a string "No I'm not hungry", converts it to bytes and sends it to Server through UDP
4) Server receives bytes, converts them to string, compares the string in a switch statement with a set of predefined strings
5) Case "No I'm not hungry" is met, logic runs and server sets the Client's "isHungry" variable to "false"
This all works properly ( for now eheh ), but before i keep going and make a huge project using this system, I just wanted to know if I'm doing things correctly.
My opinion currently is that the system is kinda hard to maintain because I'll end up having a huge amount of predefined strings to compare to.
Am i on the right track? Is there a much better way of doing this? My spider senses tell me that the way i'm doing it makes this way more complex than it should be
16 Replies
it sounds like you want to know about https://learn.microsoft.com/en-us/dotnet/standard/serialization/
Serialization - .NET
This article provides information about .NET serialization technologies, including binary serialization, XML and SOAP serialization, and JSON serialization.
I did read a bit about serialization but I'm probably not understanding it.
Assuming I use xml serialization, Applying it to the example above, am I not just adding an extra step? I'd serialize the string before sending it, deserialize it while receiving, but I'd still have to compare the string in an if or switch statement to apply logic to it
thanks for the answer btw
Do you need to use strings? It seems like the communication boils down to "if I receive these bytes, I should do this thing"
Sometimes I need to send different data types, for example an int mixed together with a string. Like:
//Server
sendbuf = Encoding.ASCII.GetBytes($"Your Latency is:{answeringClient.latency},Add this amount of ticks:{ticksToAdd}");
//Client
string receivedString = Encoding.ASCII.GetString(receivedBytes, 0, receivedBytes.Length);
string[] splitString = receivedString.Split(",");
string latency = splitString[0].Substring(splitString[0].LastIndexOf(":") + 1);
string ticksToAdd = splitString[1].Substring(splitString[1].LastIndexOf(":") + 1);
logHandler.ConsoleLog($"Received latency = {latency} Ticks to add = {ticksToAdd}");
Eventually i'd love to pass more complex information, for example if I create an object server-side and I want the client to create it too
Sorry if i may not be explaining myself properly but I'm learning along the way with this project so I may be missing crucial informations
if you only have messages that are strings, there's nothing to serialize
the point of serialization is to send and receive complex objects
and your data is complex given that example
instead of a human-readable string you should send a class containing the latency and ticks to add
serialization is what lets you basically turn a class into a string to send over the network, then turn it back into a class on the other side
using a standard format that's efficient and less error prone than creating and processing strings by hand
I think i understand what serialization can be used for but I'm having troubles implementing it
Like
1) server sends UDP packet to client with string "alive?"
2) client receives UDP packet, reads the received string "alive?" and decides which method to use. Decides to use method which sends "yes" to server
3) server receives UDP packet, reads the received string "yes" and decides which method to use. Decides to use method which calculates latency and ticksToAdd
4) server creates RemoteClient remoteClient object, with int latency and int ticksToadd. Populates the fields with values calculated in step 3, serializes RemoteClient remoteClient and sends it to client.
5) client receives UDP packet. There is no string in the packet only a RemoteClient serialized object. How can the client know that it has to deserialize it? There is no string that tells the client what to do
you would include information in the packet saying what kind of message it is
how could that be done?
I mean if i create a packet whic has a string, then at the end of the string the RemoteClient object, how does the receiving end know where the string ends and where the RemoteClient data starts
one option - a general "message" object that contains the message type and message data
that is what serialization is for
you no longer send any raw strings
so I send a serialized Message object which has string orderString and RemoteClient remoteClient. Client deserializes Message, understands what to do from orderString and deserializes remoteClient?
basically
your message wouldn't contain a RemoteClient specifically
it would be a generalized container that you use to send all messages
then the other end can just assume that anything it receives is a Message object and go from there
let's say for the sake of simplicity i only use this for RemoteClient, I would need to do a double serialization? I would have to serialize Message, but Message contains RemoteClient which has to be serialized aswell?
you could have multiple serialization steps, that's probably the easier way to do it
you could also have a format that encodes each message type as a fixed length identifier and send that before your specific message data, then the other side knows to always read that fixed length and use it to look up what the data is
there are lots of options, more than i can explain here
alright thank you very much for your help you cleared up a lot of stuff for me
I'm gonna do some tests and see what method works best/is easier to implement
I think i'll go with the identifier for now as it seems easier to me since I don't have much experience in serialization and double serialization would complicate stuff a bit too much
ty
I've implemented basic serialization and deserialization and my code is already looking much better and is much easier to maintain
Thanks again, i'll close the post now
to me this lack the substance
i mean you are sending and receiving strings, ok, but that's not really the important part to me
it's all the ecosystem around this that matters
like what about error recovery and flow control, since this is udp
what about how you manage and generate the strings
what's the architecture of the network and of your software
what's the size of the data, what will be the load on the network
how much strings will be modified to accomodate new features
i mean you study your problem first, extrapolate some parameters, and then realize the solution
sending and receiving bytes it's just what the client enables you to do, i don't see anything that is a project above that
Was this issue resolved? If so, run
/close
- otherwise I will mark this as stale and this post will be archived until there is new activity.