I have started my first Socket project and I'm wondering how should I read and send data via
server <=> client
Should I make serialized class, use maximum buffer size and don't keep my mind with bytes, or make it all synchronous, read and send bytes only when needed.
Serialize(part of code):
// TcpDLL
[Serializable]
public class SerializedData {
public string Message { get; set; }
public DataTypes Type { get; set; }
public object Data { get; set; }
}
private void ReadStream() {
// ...
stream.BeginRead(buffer, 0, MAX_BUFFER_SIZE, new AsyncCallback(ReadAsync), stream);
// ...
}
private void ReadAsync() {
// ...
var dataInfo = (SerializedData)BinaryFormatter.Deserialize(new MemoryStream(buffer));
if (dataInfo.Type == DataTypes.Register) {
var data = (RegisterClass)dataInfo.Data;
}
// ...
}
Or make it completely synchronous:
private void ReadStream() {
int bytes = ReadBytesInt(4); // read size of string Message
string Message = ReadBytesStr(bytes);
var Type = (DataTypes)ReadBytesInt(4);
bytes = ReadBytesInt(4); // read size of Data
if (Type == DataTypes.Register) {
RegisterClass.ReadStream();
}
// ...
}
private void RegisterClass.ReadStream() {
int id = ReadBytesInt(4);
// Read rest of data
}
Or maybe combine it? Something like this:
private void ReadStream() {
int bytes = ReadBytesInt(4); // read size of SerializedData object
var dataInfo = (SerializedData)ReadBytesAndDeserialize(bytes);
// ...
}
What is the best way and why? Is this better to read more data once or make it as small as possible?
TCP is a streaming protocol, so if you want to send more than a single message, you should provide some way to indicate to the other end when a message is completed.
This is usually done by first sending the size of the message, followed by the message itself. So yes, the combination of what you're doing now is what people usually do.
However you should keep in mind that data might not be received all in once - TCP only ensures that data is received in the order it was sent, and subsequet. In other words:
The amount of data read is not really relevant, incoming data is stored at the socket level, and your read operation just empties that local buffer. Of course reading byte by byte is not recommended.
Size matters, and there's no need to specify a size for each separate field. However don't worry about a few bytes extra.