I've been researching and came to the conclusion that using StreamWriter.WriteLine
is not the best idea. However, using StreamWriter.Write
and prefixing the actual message bytes size and sending it from the client to the server so the server will know where to start reading and where to stop reading.
Here is working code I have so far:
public void Send(string header, Dictionary<string, string> data)
{
new Thread(() =>
{
Thread.CurrentThread.IsBackground = true;
if (stream.CanRead)
{
socketReady = true;
}
if (!socketReady)
{
return;
}
JsonData SendData = new JsonData();
SendData.header = "1x" + header;
foreach (var item in data)
{
SendData.data.Add(item.Key.ToString(), item.Value.ToString());
}
SendData.connectionId = connectionId;
string json = JsonConvert.SerializeObject(SendData);
byte[] JsonToBytes = Encoding.ASCII.GetBytes(json);
byte[] lengthArray = BitConverter.ToInt32(JsonToBytes, 0);
stream.Write(lengthArray, 0, lengthArray.Length);
stream.Write(JsonToBytes, 0, JsonToBytes.Length);
stream.Flush();
Debug.Log("Client World:" + json);
}).Start();
}
This is how I send the data to the server. As you see I'm using writer.WriteLine(json);
I know that I need to change that first to calculate the size of the message in bytes and send it as a prefix.
Here is how i read the data at the server:
//Console.WriteLine("Call");
if (!serverStarted)
{
return;
}
foreach (ServerClient c in clients.ToList())
{
// Is the client still connected?
if (!IsConnected(c.tcp))
{
c.tcp.Close();
disconnectList.Add(c);
Console.WriteLine(c.connectionId + " has disconnected.");
CharacterLogout(c.connectionId);
continue;
//Console.WriteLine("Check for connection?\n");
}
else
{
// Check for message from Client.
NetworkStream s = c.tcp.GetStream();
if (s.DataAvailable)
{
string data = c.streamReader.ReadLine();
if (data != null)
{
OnIncomingData(c, data);
}
}
//continue;
}
}
for (int i = 0; i < disconnectList.Count - 1; i++)
{
clients.Remove(disconnectList[i]);
disconnectList.RemoveAt(i);
}
As you see I'm using c.streamReader.ReadLine();
which is reading the Line as a delimiter. I don't want that. I need to change it to check the message size in bytes, read it and then send it to OnIncomingData(c, data);
as an actual message without the bytes prefix.
However, I don't know how to calculate the actual message size in the client, form it and send it. I'm also not aware how to proceed it in the reading in the server.
Can you please review my code and make edits to my code so it will work in this manner and I can understand how it works?