sending xml over tcp/ip

B

Bob Garbados

I need to construct an xml document, send it to a service over tcp/ip to a
specified port, receive the xml response, and process the xml response. I
can create the xml document to send, but what's the best way to move the
data from an XmlDocument to a Byte array? Currently I paste the xml into a
textbox and send it with the following code:

Dim tcpClient As New System.Net.Sockets.TcpClient
tcpClient.Connect("127.0.0.1", 10000)
Dim networkStream As NetworkStream = tcpClient.GetStream()
Dim strXml As String
strXml = txtXmlInput.Text.ToString
Dim sendBytes As Byte() = Encoding.ASCII.GetBytes(strXml)
networkStream.Write(sendBytes, 0, sendBytes.Length)
Dim strXml As String
strXml = txtXmlInput.Text.ToString
Dim sendBytes As Byte() = Encoding.ASCII.GetBytes(strXml)
networkStream.Write(sendBytes, 0, sendBytes.Length)

I can get the returned xml stream into a string, but how would I get the
returned byte array into an XmlDocument? Here's how I currently get the
returned stream into a string:

Dim bytes(tcpClient.ReceiveBufferSize) As Byte
NetworkStream.Read(bytes, 0, CInt(tcpClient.ReceiveBufferSize))
Dim returndata As String = Encoding.ASCII.GetString(bytes)

Thanks.
 
J

Joerg Jooss

Bob said:
I need to construct an xml document, send it to a service over tcp/ip
to a specified port, receive the xml response, and process the xml
response. I can create the xml document to send, but what's the best
way to move the data from an XmlDocument to a Byte array? Currently
I paste the xml into a textbox and send it with the following code:

Dim tcpClient As New System.Net.Sockets.TcpClient
tcpClient.Connect("127.0.0.1", 10000)
Dim networkStream As NetworkStream = tcpClient.GetStream()
Dim strXml As String
strXml = txtXmlInput.Text.ToString
Dim sendBytes As Byte() = Encoding.ASCII.GetBytes(strXml)
networkStream.Write(sendBytes, 0, sendBytes.Length)
Dim strXml As String
strXml = txtXmlInput.Text.ToString
Dim sendBytes As Byte() = Encoding.ASCII.GetBytes(strXml)
networkStream.Write(sendBytes, 0, sendBytes.Length)

Unless you're sure about it, you should better use Encoding.UTF8,
otherwise any non-ASCII character will be dropped.

But you can actually write the document directly to the network stream:

xmlDocument.Save(networkStream);
I can get the returned xml stream into a string, but how would I get
the returned byte array into an XmlDocument? Here's how I currently
get the returned stream into a string:

Dim bytes(tcpClient.ReceiveBufferSize) As Byte
NetworkStream.Read(bytes, 0, CInt(tcpClient.ReceiveBufferSize))
Dim returndata As String = Encoding.ASCII.GetString(bytes)

You wouldn't believe it ;-)
xmlDocument.Load(networkStream);

Cheers,
 
B

Bob Garbados

Thanks Joerg, but I'm still getting an error. I probably misunderstood what
to change, so here's my new code:

Try
Dim xDoc As XmlDocument
xDoc = New XmlDocument
xDoc.Load("C:\Inetpub\wwwroot\Sockets\Request.xml")
Dim client As New TcpClient("127.0.0.1", 10000)
Dim ns As NetworkStream = client.GetStream

If ns.CanRead And ns.CanWrite Then
xDoc.Save(ns)
xDoc.Load(ns)
End If

Catch ex As Exception
lblMessage.Text = ex.ToString
End Try

The exeption that's getting thrown happens on the xDoc.Load(ns) is:
System.IO.IOException: Unable to read data from the transport
connection. ---> System.Net.Sockets.SocketException: An established
connection was aborted by the software in your host machine at
System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size,
SocketFlags socketFlags) at System.Net.Sockets.NetworkStream.Read(Byte[]
buffer, Int32 offset, Int32 size) --- End of inner exception stack trace ---
at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32
size) at System.Xml.XmlStreamReader.Read(Byte[] data, Int32 offset, Int32
length) at System.Xml.XmlScanner..ctor(XmlStreamReader reader, XmlNameTable
ntable, Encoding enc) at System.Xml.XmlScanner..ctor(XmlStreamReader reader,
XmlNameTable ntable) at System.Xml.XmlTextReader..ctor(String url, Stream
input, XmlNameTable nt) at System.Xml.XmlTextReader..ctor(Stream input,
XmlNameTable nt) at System.Xml.XmlDocument.Load(Stream inStream) at
Sockets.WebForm1.ReadXmlNew() in
C:\Inetpub\wwwroot\Sockets\Sockets.aspx.vb:line 242

I also tried declaring another XmlDocument to hold the response and the same
exception was thrown.

Did I miss something obvious?
 
J

Joerg Jooss

Bob said:
Thanks Joerg, but I'm still getting an error. I probably
misunderstood what to change, so here's my new code:

Try
Dim xDoc As XmlDocument
xDoc = New XmlDocument
xDoc.Load("C:\Inetpub\wwwroot\Sockets\Request.xml")
Dim client As New TcpClient("127.0.0.1", 10000)
Dim ns As NetworkStream = client.GetStream

If ns.CanRead And ns.CanWrite Then
xDoc.Save(ns)
xDoc.Load(ns)
End If

Catch ex As Exception
lblMessage.Text = ex.ToString
End Try

The exeption that's getting thrown happens on the xDoc.Load(ns) is:
System.IO.IOException: Unable to read data from the transport
connection. ---> System.Net.Sockets.SocketException: An established
connection was aborted by the software in your host machine at
System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32
size, SocketFlags socketFlags) at
System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset,
Int32 size) --- End of inner exception stack trace --- at
System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset,
Int32 size) at System.Xml.XmlStreamReader.Read(Byte[] data, Int32
offset, Int32 length) at System.Xml.XmlScanner..ctor(XmlStreamReader
reader, XmlNameTable ntable, Encoding enc) at
System.Xml.XmlScanner..ctor(XmlStreamReader reader, XmlNameTable
ntable) at System.Xml.XmlTextReader..ctor(String url, Stream input,
XmlNameTable nt) at System.Xml.XmlTextReader..ctor(Stream input,
XmlNameTable nt) at System.Xml.XmlDocument.Load(Stream inStream) at
Sockets.WebForm1.ReadXmlNew() in
C:\Inetpub\wwwroot\Sockets\Sockets.aspx.vb:line 242

I also tried declaring another XmlDocument to hold the response and
the same exception was thrown.

Did I miss something obvious?

Maybe there's something wrong with the character encoding. Another
option is to use an XmlTextReader to read from the stream. This gives
you a little more control over what's going on under the hood. The same
applies to writing using an XmlTextWriter.

Cheers,
 
B

Bob Garbados

couldn't get it to work with the xmltextwriter and xmltextreader, but this
does work:

Dim client As New TcpClient("127.0.0.1", 10000)
Dim ns As NetworkStream = client.GetStream

Dim xDoc As XmlDocument
xDoc = New XmlDocument
xDoc.Load("C:\Inetpub\wwwroot\Sockets\Request01.xml")

If ns.CanRead And ns.CanWrite Then
Dim sendBytes As Byte() = Encoding.UTF8.GetBytes(xDoc.OuterXml)
ns.Write(sendBytes, 0, sendBytes.Length)

Dim responseBytes(client.ReceiveBufferSize) As Byte
ns.Read(responseBytes, 0, CInt(client.ReceiveBufferSize))

Dim xResponse As XmlDocument
xResponse = New XmlDocument
xResponse.LoadXml(Encoding.UTF8.GetString(responseBytes))

'do great things to the response xml
...

End If
client.Close()
ns.Close()

If this can be done in a better manner, I'd love to see ideas.



Joerg Jooss said:
Bob said:
Thanks Joerg, but I'm still getting an error. I probably
misunderstood what to change, so here's my new code:

Try
Dim xDoc As XmlDocument
xDoc = New XmlDocument
xDoc.Load("C:\Inetpub\wwwroot\Sockets\Request.xml")
Dim client As New TcpClient("127.0.0.1", 10000)
Dim ns As NetworkStream = client.GetStream

If ns.CanRead And ns.CanWrite Then
xDoc.Save(ns)
xDoc.Load(ns)
End If

Catch ex As Exception
lblMessage.Text = ex.ToString
End Try

The exeption that's getting thrown happens on the xDoc.Load(ns) is:
System.IO.IOException: Unable to read data from the transport
connection. ---> System.Net.Sockets.SocketException: An established
connection was aborted by the software in your host machine at
System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32
size, SocketFlags socketFlags) at
System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset,
Int32 size) --- End of inner exception stack trace --- at
System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset,
Int32 size) at System.Xml.XmlStreamReader.Read(Byte[] data, Int32
offset, Int32 length) at System.Xml.XmlScanner..ctor(XmlStreamReader
reader, XmlNameTable ntable, Encoding enc) at
System.Xml.XmlScanner..ctor(XmlStreamReader reader, XmlNameTable
ntable) at System.Xml.XmlTextReader..ctor(String url, Stream input,
XmlNameTable nt) at System.Xml.XmlTextReader..ctor(Stream input,
XmlNameTable nt) at System.Xml.XmlDocument.Load(Stream inStream) at
Sockets.WebForm1.ReadXmlNew() in
C:\Inetpub\wwwroot\Sockets\Sockets.aspx.vb:line 242

I also tried declaring another XmlDocument to hold the response and
the same exception was thrown.

Did I miss something obvious?

Maybe there's something wrong with the character encoding. Another
option is to use an XmlTextReader to read from the stream. This gives
you a little more control over what's going on under the hood. The same
applies to writing using an XmlTextWriter.

Cheers,
 
J

Joerg Jooss

Bob said:
couldn't get it to work with the xmltextwriter and xmltextreader, but
this does work:

Out of curiostiy -- why? Problems with the API or just a "no go"? It's
somewhat hard for me to check what's going on since I'm not in the mood
to write my own little client/server package for testing rigth now ;-)

(Code looks fine save for exception handling -- close your streams in a
finally block).

Cheers,
 
B

Bob Garbados

I couldn't write to the stream with a xmlTextWriter, not sure exactly why.
When I tried to read the stream into a xmlTextReader the following exception
was thrown:

System.IO.PathTooLongException: The path is too long after being fully
qualified. Make sure path is less than 260 characters. at
System.IO.Path.nGetFullPathHelper(String path, Char[] invalidPathChars,
Char[] whitespaceChars, Char directorySeparator, Char altDirectorySeparator,
Char volumeSeparator, Boolean fullCheck, String& newPath) at
System.IO.Path.GetFullPathInternal(String path) at
System.IO.Path.GetFullPath(String path) at
System.Xml.XmlResolver.ResolveUri(Uri baseUri, String relativeUri) at
System.Xml.XmlTextReader..ctor(String url, XmlNameTable nt) at
System.Xml.XmlDocument.Load(String filename)

I'm stumped on why the exception was getting thrown. I would like to find
some more time to mess around with this again and I'll reply to this post
with an update if I have one.

Thanks for the tip on exception handling, I have it all in a try catch
block... just wanted to post the part of the code that was giving me
problems.
 
J

Joerg Jooss

Bob said:
I couldn't write to the stream with a xmlTextWriter, not sure exactly
why. When I tried to read the stream into a xmlTextReader the
following exception was thrown:

System.IO.PathTooLongException: The path is too long after being fully
qualified. Make sure path is less than 260 characters. at
System.IO.Path.nGetFullPathHelper(String path, Char[]
invalidPathChars, Char[] whitespaceChars, Char directorySeparator,
Char altDirectorySeparator, Char volumeSeparator, Boolean fullCheck,
String& newPath) at System.IO.Path.GetFullPathInternal(String path) at
System.IO.Path.GetFullPath(String path) at
System.Xml.XmlResolver.ResolveUri(Uri baseUri, String relativeUri) at
System.Xml.XmlTextReader..ctor(String url, XmlNameTable nt) at
System.Xml.XmlDocument.Load(String filename)

I'm stumped on why the exception was getting thrown. I would like to
find some more time to mess around with this again and I'll reply to
this post with an update if I have one.

The stacktrace isn't really what I've expected -- it starts with
XmlDocument.Load(string). Using an XmlReader explicitly would look like
this:

XmlDocumenent xmlDocument = new XmlDocument();
using (XmlReader reader = new XmlTextReader(networkStream)) {
xmlDocument.Load(reader);
}

Cheers,
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,764
Messages
2,569,567
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top