C# Tcpclient: Send Serialized Objects Using Separators

Serializing object ready to send over TCPClient Stream

Assuming you have a class House (available on both sides of your connection) looking like this:

[Serializable]
public class House
{
public string Street { get; set; }
public string ZipCode { get; set; }
public int Number { get; set; }
public int Id { get; set; }
public string Town { get; set; }
}

You can serialize the class into a MemoryStream. You can then use in your TcpClient connection like this:

// Create a new house to send house and set values.
var newHouse = new House
{
Street = "Mill Lane",
ZipCode = "LO1 BT5",
Number = 11,
Id = 1,
Town = "London"
};

var xmlSerializer = new XmlSerializer(typeof(House));
var networkStream = tcpClient.GetStream();
if (networkStream.CanWrite)
{
xmlSerializer.Serialize(networkStream, newHouse);
}

Of course you have to do a little more investigation to make the program running without exception. (e.g. Check memoryStream.Length not to be greater than an int, a.s.o.), but I hope I gave you the right suggestions to help you on your way ;-)

Casting different objects from TcpClient serialized object stream?

I am assuming the objects have already deserialized correctly. I would use a big if object is type then... else...

object deserializedObject = Deserialize(....);
if (deserializedObject is string)
ProcessString ((string)deserializedObject);
else if (deserializedObject is byte[])
ProcessBytes ((byte[])deserializedObject);
else if (deserializedObject is Uri)
ProcessUri ((Uri)deserializedObject);
else
throwOrLog (deserializedObject);

Serialized data on tcpclient needs to state amount?

If you use a text based serializer(for ex, Json), you can utilize StreamReader's ReadLine and StreamWriter's WriteLine (created from tcpClient.GetStream).

Your code would be something like

 writer.WriteLine(JsonConvert.SerializeObject(commData))

and to get the data on the other end

var myobj = JsonConvert.DeserializeObject<MyCommunicationData>(reader.ReadLine())

--EDIT--

//**Server**
Task.Factory.StartNew(() =>
{
var reader = new StreamReader(tcpClient.GetStream());
var writer = new StreamReader(tcpClient.GetStream());
while (true)
{
var myobj = JsonConvert.DeserializeObject<MyCommunicationData>(reader.ReadLine());
//do work with obj
//write response to client
writer.WriteLine(JsonConvert.SerializeObject(commData));
}
},
TaskCreationOptions.LongRunning);

How can I send multiple string messages from client to server using a single instance of TcpClient?

If you debug your server, you'll see that it does receive data. You're just not displaying the data, because the only output your server does is after the loop when the byte count returned is 0: Console.WriteLine($"Message:{ dataReceived }\n");. The byte count will only be 0 when the underlying socket has been shutdown. That never happens because your client is stuck in an infinite loop.

A better approach, for a simple text-based client/server example like this, is to use StreamWriter and StreamReader with line-based messages, i.e. WriteLine() and ReadLine(). Then the line breaks serve as the message delimited, and your server can write the message each time it receives a new line.

Note also that in your example above, you are assuming that each chunk of data contains only complete characters. But you're using UTF8 where characters can be two or more bytes, and TCP doesn't guarantee how bytes that are sent are grouped. Using StreamWriter and StreamReader will fix this bug too, but if you wanted to do it explicitly yourself, you can use the Decoder class, which will buffer partial characters.

For some examples of how to correctly implement a simple client/server network program like that, see posts like these:

.NET Simple chat server example

C# multithreading chat server, handle disconnect

C# TcpClient: Send serialized objects using separators?

Multiple Clients on TCPListener C# / Server sending Data

Where I am not the best with C# this post Server Client send/receive simple text how to create C# simple server, and should fix the first issue of the client not being able to recive data from the server.

As for the second issue not being able to support mulitple connections, this could be to do with there is no threading, so the question is do you want to create a C# webserver or a C# application which utilizes TCP communication to a server.

if the answer is the latter, then I would look to installing tried and tested server such a Apache or Nginx. this will allow the server to handle multiple requests on your behalf and skip having to handle multiple connections and threads, while you are learning more about the client server relationship. also this article may help setting up the fastcgi environment for the appliction http://www.mono-project.com/docs/web/fastcgi/nginx/

otherwise then you will have to look at how to handle multiple clients which this post looks like it could help TCP server with multiple Clients

How to send an object through a socket C#

You have to "serialize" the objects, and and de-serialize them on the other side. See http://msdn.microsoft.com/en-us/library/system.serializableattribute.aspx for information about that.

You have to be careful though, if something happens to the connection while sending the data, you might have not enough data to completely re-create the objects, and your program may fail in some unexpected place. Only create the objects if you received everything.



Related Topics



Leave a reply



Submit