473,780 Members | 2,229 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

xmlserializer and sockets

hi, i have some problems with my client talk to my server...
i am using xmlserializer to serialize object and send them to the other
side of the connection. I need to send / recive by both client and
server. client after login waits all the time listening for objects on a
thread, and sends objects on users events on the main thread. server
waits connections, start a new thread for each connection and after
validating login waits for object, and answer with an object to every
incoming object.

If i send only one packet, all works fine, i tryed many solution but i
cannot send 2 packets, or send and recive...

here is my code:

LoginPacket is a class with informations

SERVER SIDE:
the method run of this class is launched as a thread to serve a client,
with a socket initializated (and passed as parameter)
now for testing it will only waits for 2 login packets

public class ServeClient {
private Socket sock;
public ServeClient(Soc ket s) {
this.sock = s;
}
public void Run(){
NetworkStream networkStream = new NetworkStream(s ock);

//waiting for login request
LoginPacket lp;
this.Deserializ eMessage( networkStream, out lp);

LoginPacket lp2;
this.Deserializ eMessage( networkStream, out lp2);
Console.WriteLi ne("Incoming login request: {0}", lp.Nick);

networkStream.C lose();
sock.Close();
}
// this will deserialize the message, and put it in message
public bool DeserializeMess age(NetworkStre am networkStream,o ut
LoginPacket message) {
Byte []buffer=new Byte[500];
XmlSerializer deserializer=ne w XmlSerializer(t ypeof(LoginPack et));
int count=networkSt ream.Read(buffe r,0,buffer.Leng th);
if(count <= 0) {
message=null;
return false;
}
MemoryStream memoryStream=ne w MemoryStream(bu ffer,0,count);
message= ((LoginPacket)d eserializer.Des erialize(memory Stream));
return true;
}
}

CLIENT SIDE:
// run is launched as a thread, this thread will wait listening after
// login succed. now for testing it will only send 2 login requests
class ListenerThread {
private TcpClient client; //FIXME : it is no syncronized
public void Run() {
client = new TcpClient( "localhost" , 6666);;
LoginPacket login = new LoginPacket( PacketType.LOGI N_REQUEST,
"nick", "pass");

LoginPacket login2 = new LoginPacket( PacketType.LOGI N_REQUEST,
"nick2", "pass2");
this.Send(login );
this.Send(login 2);

client.Close();

}
//send a loginpacket
public void Send(LoginPacke t message) {
NetworkStream netWorkStream=n ull;
XmlSerializer serializer=new XmlSerializer(m essage.GetType( ));
//Fixme: metterlo fuori dal metodo
netWorkStream = client.GetStrea m();
Stream stream=(Stream) netWorkStream;
serializer.Seri alize(stream,me ssage);
}
}

thx if someone can solve my problems.
Nov 16 '05 #1
4 5413
What is the error message you get?

Anyway, there are some invalid assumptions in your code. See below:

"Ultrakorne " <ul********@fre eweb.org> wrote in message
news:1S******** **************@ news4.tin.it...
hi, i have some problems with my client talk to my server...
i am using xmlserializer to serialize object and send them to the other
side of the connection. I need to send / recive by both client and server.
client after login waits all the time listening for objects on a thread,
and sends objects on users events on the main thread. server waits
connections, start a new thread for each connection and after validating
login waits for object, and answer with an object to every incoming
object.

If i send only one packet, all works fine, i tryed many solution but i
cannot send 2 packets, or send and recive...

here is my code:

LoginPacket is a class with informations

SERVER SIDE:
the method run of this class is launched as a thread to serve a client,
with a socket initializated (and passed as parameter)
now for testing it will only waits for 2 login packets

public class ServeClient {
private Socket sock;
public ServeClient(Soc ket s) {
this.sock = s;
}
public void Run(){
NetworkStream networkStream = new NetworkStream(s ock);

//waiting for login request
LoginPacket lp;
this.Deserializ eMessage( networkStream, out lp);

LoginPacket lp2;
this.Deserializ eMessage( networkStream, out lp2);
Console.WriteLi ne("Incoming login request: {0}", lp.Nick);

networkStream.C lose();
sock.Close();
}
// this will deserialize the message, and put it in message
public bool DeserializeMess age(NetworkStre am networkStream,o ut
LoginPacket message) {
Byte []buffer=new Byte[500];
XmlSerializer deserializer=ne w XmlSerializer(t ypeof(LoginPack et));
int count=networkSt ream.Read(buffe r,0,buffer.Leng th);
if(count <= 0) {
message=null;
return false;
}


You assume that 'buffer' now contains the serialized data for one
LoginPacket, but this is not necessarily the case. It could contain data for
half of a LoginPacket, one and a half, two LoginPackets, or anything in
between. The basic issue here is that TCP is a stream-oriented protocol and
the stuff you send arrives to its destination as an unstructured stream of
bytes.

One way to solve the problem would be to first send the size of the
serialized LoginPacket (number of bytes) and then the LoginPacket itself.
The receiver would first read the size and then the expected number of bytes
into the buffer. The receiver should deserialize the LoginPacket only after
the expected number of bytes have arrived and are in the buffer.

Another way that might work (don't have the time to try it now) would be to
have the XmlSerializer deserialize straight from the NetworkStream.

Regards,
Sami

Nov 16 '05 #2
> Another way that might work (don't have the time to try it now) would be
to
have the XmlSerializer deserialize straight from the NetworkStream.


I was thinking that too. However it probably exposes server to DoS attacks.
If you know the len before hand, you can decide if want to read that many
bytes or not. So the safe way is to send the len (i.e. uint) before hand
and read that many bytes, then deserialize that byte[]. Maybe something
like:

// Object
XmlRequest xr = new XmlRequest();
xr.Data = "Hello";

// Serialize it.
MemoryStream ms = new MemoryStream();
ms.Position = 4; // leave 4 bytes for our len.
XmlSerializer ser = new XmlSerializer(t ypeof(XmlReques t));
ser.Serialize(m s, xr);
int size = (int)ms.Length - 4;
byte[] lenBytes = BitConverter.Ge tBytes(size);
ms.Position = 0;
ms.Write(lenByt es, 0, 4);

// Write ms bytes to socket.

// Deserialize it.
ms.Position = 0; // pretent we blocking on first byte.
ms.Read(lenByte s, 0, 4); // pretent we read four bytes.
int len = BitConverter.To Int32(lenBytes, 0);
byte[] bytes = new byte[len];
ms.Read(bytes, 0, len); // read len count data bytes only.
string xmlString = Encoding.UTF8.G etString(bytes, 0, bytes.Length); //
Used by Stream overload on xmlserializer.
Console.WriteLi ne("Raw:"+xmlSt ring);
XmlSerializer ser2 = new XmlSerializer(t ypeof(XmlReques t));
using (StringReader sr = new StringReader(xm lString))
{
xr = (XmlRequest)ser .Deserialize(sr );
Console.WriteLi ne("Data:"+xr.D ata);
}

--
William Stacey, MVP
http://mvp.support.microsoft.com
Nov 16 '05 #3
Sami Vaaraniemi wrote:
What is the error message you get?

Anyway, there are some invalid assumptions in your code. See below:

i have changed the recive method and make it simpler:

public LoginPacket DeserializeMess age() {
NetworkStream networkStream = new NetworkStream(s ock);
LoginPacket message = null;
try {
message = ((LoginPacket)d eserializer.Des erialize(networ kStream));
} catch(Exception e) { Console.WriteLi ne("EXC 3"); return null; }
finally {
networkStream.C lose();
}
return message;
}

deserializer is XmlSerializer = new XmlSerializer(t ypeof(LoginPack et));

the problem is the same: exception is raised by .Deserialize:
System.Xml.XmlE xception: XML declaration cannot appear in this state.
Line 5, position 20.

William Stancey wrote:
I was thinking that too. However it probably exposes server to DoS
attacks.
If you know the len before hand, you can decide if want to read that
many
bytes or not. So the safe way is to send the len (i.e. uint) before
hand
and read that many bytes, then deserialize that byte[]. Maybe
something like:


thanks for your hit, but first i have to solve and understand whats
wrong with my code
Nov 16 '05 #4
I did a bit of digging and here's what I found out.

It seems that XmlSerializer.D eserialize blocks until it gets end-of-file or
its internal buffer of 4k is full. If the sender closes the socket after the
LoginPacket is sent, then it works and the deserialized object is returned
properly. But this is hardly a solution as you want to send more than just
the one LoginPacket. On the other hand, if there is more data coming from
the socket after the last closing tag, then XML parsing fails and there is
an exception.

Bottom line, it appears you cannot call XmlSerializer.D eserialize with a
NetworkStream, or at least I could not figure out how to make it work. Even
if it were possible, you probably don't want to do it this way as the server
would be vulnerable to a DoS attack just like William pointed out.

So the solution is to first send the length of the serialized object, and
then the serialized object itself. The receiver should copy the bytes from
the socket into a temporary buffer, then deserialize out of the buffer.

Alternatively, you could use the BinaryFormatter instead of XmlSerializer as
it does not suffer from the blocking problem.

Regards,
Sami

"ultrakorne " <ul********@par anoici.org> wrote in message
news:41******** ******@paranoic i.org...
Sami Vaaraniemi wrote:
What is the error message you get?

Anyway, there are some invalid assumptions in your code. See below:


i have changed the recive method and make it simpler:

public LoginPacket DeserializeMess age() {
NetworkStream networkStream = new NetworkStream(s ock);
LoginPacket message = null;
try {
message = ((LoginPacket)d eserializer.Des erialize(networ kStream));
} catch(Exception e) { Console.WriteLi ne("EXC 3"); return null; }
finally {
networkStream.C lose();
}
return message;
}

deserializer is XmlSerializer = new XmlSerializer(t ypeof(LoginPack et));

the problem is the same: exception is raised by .Deserialize:
System.Xml.XmlE xception: XML declaration cannot appear in this state. Line
5, position 20.

William Stancey wrote:
I was thinking that too. However it probably exposes server to DoS
attacks.
If you know the len before hand, you can decide if want to read that
many
bytes or not. So the safe way is to send the len (i.e. uint) before
hand
and read that many bytes, then deserialize that byte[]. Maybe
something like:


thanks for your hit, but first i have to solve and understand whats wrong
with my code

Nov 16 '05 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
5430
by: Stuart Robertson | last post by:
I am trying to find a solution that will allow me to use XmlSerializer to serialize/deserialize a collection of objects where a given object is shared between two or more other objects, and not create duplicate XML representations of the shared object, but instead use IDREFs to refer to the shared object. The XML I'm trying to produce is as follows (where "href" is an IDREF): <?xml version="1.0" encoding="utf-8"?> <MyRootClass...
1
4322
by: Bluetears76 | last post by:
Hi I have a hirachy of classes which are Message(base), then FileMessage and ChatMessage (extended) I want to serialize the objects and when i am deserizaling i dont know if i am getting FileMessage or ChatMessage. So how to get that object and use it I have written following code for serialization public void Send(Message message) { NetworkStream netWorkStream=null;
3
7003
by: Anthony Bouch | last post by:
Hi I've been reading using the XmlSerializer with custom collections. I've discovered that when serializing a custom collection (a class that implements ICollection, IList etc.) the XmlSerializer will only serialize the collection items - with the default root as ArrayofMyItems etc. My custom collection class has some additional public properties that I would like to include in the serialization above the items element array (in
3
4517
by: Loui Mercieca | last post by:
Hi, I have created a class, named FormField , which basically contains two fields, name and value. I have set the tag before the class and the field is set as an XmlAttribute whil the name as XmlText. In my main class, i have created an arraylist which contains a collection of this class FormField. Basically its: public void Add( string sName, string sValue )
12
8502
by: SJD | last post by:
I've just read Christoph Schittko's article on XmlSerializer: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnxmlnet/html/trblshtxsd.asp . . . and very informative it is too. I, too, am getting nasty FileNotFound exceptions. I've read, and digested the article, and I think I've found a bug -- it's difficult to track, though it does happen often.
4
1992
by: Steve Long | last post by:
Hello, I hope this is the right group to post this to. I'm trying to serialize a class I've written and I'd like to be able to serialze to both binary and xml formats. Binary serialization is working fine but when I try to instantiate an XmlSerializer object with: Dim xmls As New XmlSerializer(GetType(CLayerDefinition)) I get the following error:
7
2318
by: Bill English | last post by:
How do I send an object from one computer to another? -- I am a 14 year old C# developer, I am completely self taught, so please don't get mad if I ask a stupid question. Thanks.
2
1766
by: Curious | last post by:
Hi, I have a similar class to the one shown below, with the main difference that it has more properties. Now I am using the enum to indicate what type of data current exists. I am using XmlSerialization to transfer the data over Sockets (TcpClient, TcpListener). Now when data is arriving at destination, MessageType is always being
3
20858
by: Curious | last post by:
Hi, I am using the following code to transfer messages between client and server. Upon running that code I am getting the following error message in method ReceiveFromClient on line Stream s =.... "An unhandled exception of type 'System.InvalidOperationException' occurred in system.dll
0
9636
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9474
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10306
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10139
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
9931
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
1
7485
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
1
4037
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
3632
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2869
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.