I try to serialize C# objects to a JSON string and then send it over a network to a server. Yet the server never gets the obejcts. I tried to play with the settings of the JsonSerializer by setting the TypeNamehandling to Obejcts, but that didn't work too. I also don't like to convert the JSON-String to bytes and send it that way, because then I need to find some way to flush the NetworkStream I'm using and currently this Stream is always open.
I don't find any solution online. I hope someone here can help me. The whole code is uploaded to my GitHub!
My Client Code:
public void Serialize(object value)
{
StreamWriter streamWriter = new StreamWriter(Stream);
JsonWriter jsonWriter = new JsonTextWriter(streamWriter);
jsonSerializer.Serialize(jsonWriter, value,typeof(Message));
}
public Message Deserialize()
{
StreamReader streamReader = new StreamReader(Stream);
JsonReader jsonReader = new JsonTextReader(streamReader);
return jsonSerializer.Deserialize<Message>(jsonReader);
}
My Server Code
public void Serialize(Stream stream, object value)
{
StreamWriter streamWriter = new StreamWriter(stream);
JsonWriter jsonWriter = new JsonTextWriter(streamWriter);
jsonSerializer.Serialize(jsonWriter, value,typeof(Message));
}
public Message Deserialize(Stream stream)
{
StreamReader streamReader = new StreamReader(stream);
JsonReader jsonReader = new JsonTextReader(streamReader);
return jsonSerializer.Deserialize<Message>(jsonReader);
}
And a message object looks like this
[Serializable]
public class StartupMessage : Message
{
public string Username { get; set; }
public StartupMessage(string username)
{
Username = username ?? throw new ArgumentNullException(nameof(username));
}
}
Edit: Some more code from my Client, which shows how and with what I send the objects:
public string Username { get; }
public string ServerIP { get; }
//private readonly BinaryFormatter Formatter;
private readonly JsonSerializer jsonSerializer;
private readonly TcpClient Server;
private readonly NetworkStream Stream;
public event EventHandler<NewMessageEventArgs> NewMessage;
public Client(string username, string serverIP)
{
Username = username ?? throw new ArgumentNullException(nameof(username));
ServerIP = serverIP ?? throw new ArgumentNullException(nameof(serverIP));
//Formatter = new BinaryFormatter();
Server = new TcpClient(ServerIP, Message.Port);
Stream = Server.GetStream();
var settings = new JsonSerializerSettings()
{
TypeNameHandling = TypeNameHandling.Objects
};
jsonSerializer = JsonSerializer.Create(settings);
}
public void Start()
{
Serialize(new StartupMessage(Username));
var recieverThread = new Thread(() =>
{
while (true)
{
Message msg = Deserialize();
if(msg is ConnectedMessage)
{
Console.WriteLine("Connected!");
}
if(msg is MessageMessage message)
{
OnNewMessage(new NewMessageEventArgs(message.Message, message.Username));
}
}
});
recieverThread.Start();
}
Edit 2:
private readonly List<ClientInfo> clientInfos;
//private readonly BinaryFormatter formatter;
private readonly TcpListener tcpListener;
private readonly JsonSerializer jsonSerializer;
public EventHandler<NewMessageEventArgs> NewMessage;
public Server()
{
clientInfos = new List<ClientInfo>();
//formatter = new BinaryFormatter();
tcpListener = new TcpListener(IPAddress.Any, Message.Port);
var settings = new JsonSerializerSettings()
{
TypeNameHandling = TypeNameHandling.Objects
};
jsonSerializer = JsonSerializer.Create(settings);
}
public void Start()
{
while (true)
{
tcpListener.Start();
TcpClient client = tcpListener.AcceptTcpClient();
var recieverThread = new Thread(() =>
{
NetworkStream stream = client.GetStream();
while (true)
{
Message msg = Deserialize(stream);
if (msg is StartupMessage startup)
{
OnNewMessage(new NewMessageEventArgs("CONNECTED", startup.Username),true);
string username = startup.Username;
clientInfos.Add(new ClientInfo(username, stream));
Serialize(stream, new ConnectedMessage());
}
if (msg is MessageMessage message)
{
OnNewMessage(new NewMessageEventArgs(message.Message, message.Username),false);
foreach (ClientInfo info in clientInfos)
{
Serialize(info.Stream, message);
}
}
}
});
recieverThread.Start();
}
}