Reputation: 629
I want to send and receive JSON over TCP. QUESTION: I have to send and receive JSON in my TCP client-server. How can I achieve it?
I use TcpListener and TcpClient to connect and I have this code:
NetworkStream stream = client.GetStream();
var serializer = new JsonSerializer();
var sr = new StreamReader(stream, new UTF8Encoding(), false);
var jsonTextReader = new JsonTextReader(sr);
var data = serializer.Deserialize(jsonTextReader).ToString();
Console.WriteLine("Received: {0}", data);
StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);
JsonWriter writer = new JsonTextWriter(sw);
writer.WriteValue('1');
byte[] buffer = Encoding.ASCII.GetBytes(writer.ToString());
stream.Write(buffer, 0, buffer.Length);
Can I do it better? The client has to receive JSON(I use Newtonsoft.Json) and I don't know if it is even good code. Maybe you write me some good practices? Or maybe some tips.
EDIT. Now I wrote something like this:
public static T DeserializeFromStream<T>(Stream stream)
{
using (var sr = new StreamReader(stream))
using (var jsonTextReader = new JsonTextReader(sr))
{
return new JsonSerializer().Deserialize<T>(jsonTextReader);
}
}
And it doesn't work because Java client send me array like: [{"name" : "logo", "session" : "i3fnj34njn780"}] So how can I fix this problem? I want call it this way: Method ar = DeserializeFromStream<Method>(client.GetStream());
Trim and Replace doesn't work for me here.
Upvotes: 1
Views: 5821
Reputation: 294407
byte[] buffer = Encoding.ASCII.GetBytes(writer.ToString());
This is incorrect. Per RFC4627:
Encoding
JSON text SHALL be encoded in Unicode. The default encoding is
UTF-8.
You are not sending JSON.
StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);
JsonWriter writer = new JsonTextWriter(sw);
This is unnecessarily writing a SB. Write directly into the network stream:
using (NetworkStream stream = client.GetStream()) {
using (TextWriter tw = new StreamWriter(stream, Encoding.UTF8)) {
using (JsonWriter writer = new JsonTextWriter(tw)) {
...
}
}
}
Also, use using
.
Plus, everything @CodeCaster says. This should be a proper Web API, not some rogue TCP server. Not only the obvious issue of having more than one request type (ie. routing), but you have to consider proxies (none will allow some arbitrary port), server authentication (you must tunnel through HTTPS and validate the server cert in the Android APP), make allowance for web caching, HTTP headers etc etc. And you need proper error states and error codes for your 'protocol', which HTTP provides out-of-the-box. And a good job would be to model a proper REST API, and likely a good data model on top of JSON, like JSON-API.
Upvotes: 2