UDP Sending an array possible?

  • Thread starter Thread starter Miro
  • Start date Start date
M

Miro

VB 2003
at the end of the code, this works great.

bytCommand = Encoding.ASCII.GetBytes("testing hello send text")
udpClient.Send(bytCommand, bytCommand.Length)

and this recieves it
Dim strReturnData As String = _
System.Text.Encoding.ASCII.GetString(receiveBytes)

Works super.
The original example i used was:
http://www.codeproject.com/vb/net/UDP_Send_Receive.asp

what I cant find is something like

System.Text.Encoding.ARRAY


Is it possible to send an array instead of a straight line of text? I know
i can make a huge string and send it and then
parse it out. But I just cant seem to find an example anywhere where anyone
has actually sent an array.

Im assuming i might need to convert an array to a byte or something and then
back. Im not really sure what to look for.

I dont know if it is possible or not.

Miro
 
Miro said:
VB 2003
at the end of the code, this works great.

bytCommand = Encoding.ASCII.GetBytes("testing hello send text")
udpClient.Send(bytCommand, bytCommand.Length)

and this recieves it
Dim strReturnData As String = _
System.Text.Encoding.ASCII.GetString(receiveBytes)

Works super.
The original example i used was:
http://www.codeproject.com/vb/net/UDP_Send_Receive.asp

what I cant find is something like

System.Text.Encoding.ARRAY


Is it possible to send an array instead of a straight line of text? I know
i can make a huge string and send it and then
parse it out. But I just cant seem to find an example anywhere where anyone
has actually sent an array.

Im assuming i might need to convert an array to a byte or something and then
back. Im not really sure what to look for.

I dont know if it is possible or not.

A socket isn't concerned about what the data is, it is only a stream of
bytes. With that in mind, you should be able to simply serialize your
array and then send the results across the wire. The receiving
application, would then simply deserialize the stream of bytes back to
an array.

That sounds simple in theory, but there are several complications to
this. Here are some of them:

1) Is the receiving application a .NET application? If not, then your
going to have to serialize the array into something other then a binary
format. There has to be an agreed upon protocol for representing the
array. If the application is a .net application, then things are
greatly simplified, since you can serialize the array to a byte array
using a binary formatter and then send the resulting byte array.

2) How does the receiving application know that what you sent is an
array? Ok, if all your sending are serialized arrays, then this isn't
a problem. But, if you are sending mixed messages, then you need to
develop a protocol to tell the receiving application that the stream of
bytes you just sent contains an array.

3) How much data does the receiving application have to get before it
has the entire array? Sockets break data up into packets, and so it is
possilbe that you may need to do several reads before you have all the
data in one message. With string data, you don't usually have to know
how much to expect up front, because most protocols specify that string
data is terminated with a \r\n (cariage return, line feed), or some
other special character. That isn't usually possilbe with pure binary
data, so you have to usually send a pre-message of some sort that tells
the receiver that they need to expect a certain amount of data...
Again, you have to come up with a protocol to negotiate with this stuff
with the receiving application.

4) It appears your using UDP for your data transmission. Ok, but this
even complicates things even further. UDP packet sizes are normally
smaller on UDP, which has the affect of making my point 3 even more
relavent - but this is even further complicated by the fact that UDP
does not guarentee that the packets will be sent in a particular order,
or even that they will arrive at all. What does that mean? It means
that you need to manually break your data into chunks (smaller then the
UDP packet size) and append a packet number to the data so that the
receiver can put the data back together in the right order at the other
end, and know if it received all of the data. This also means that if
the receiver doesn't receive all the data, that they can re-request the
packets from the sender (so, you have to usually agree upon a timeout
so that the receiver doesn't wait forever for data that will never
arrive). If I were you, unless UDP was an absolute requirement, I
would seriously consider using TCP sockets for this - they at least
guarentee order and that the data will all be sent. It greatly
decreases the complexity of your send and receives. The client just
has to know up front how much data to expect, and then can read until
it receives that much data - and it doesn't have to reorder anything
since TCP guarentees the packets will be received in order. Of course,
TCP has it's own problems - it is a connected socket, so you can't just
broadcast data out to the network. You have to send it to a specific
endpoint (IP Address/Port).

Anyway, if you have specific questions about any of this - feel free to
ask.
 
1. Is the receiving application a .NET application?
-Yes...its actually 1 exe... i wrote.

and what I do is this:
You click on an exe...( it checks the processes to see if its already
running ) ...if it isnt,
it opens a UDP port and listens.

now lets say you run the exe agian,
the exe now realizes its already running, so it sends out
"where the exe ran from, exe arg paramaters, working diretory... "
so like 3 or 4 ( lets say 100 char in length strings ).

Once its done sending, I close the application.
So instantly the exe#1 recieves the packets in another thread, so the thread
closes.
It reopens the thread...and listens some more incase its done again.

I am using UDP cause I couldnt find a TCP/IP example...plus its really for
just the local machine.
I had to come up with a way to send data to an exe file without using a
database. I
tried to stay clear of writint to a txt file. I wanted it a bit more
seamless. At one pont i was using the registry ( using the
log file ) but sometimes everyone doesnt have rights to the registry.

So thats how i stumbled upon a udp example.

2. I ony send the same thing so i was hoping i could put all 3 strings
into 1 array and send that instead of sending it one at a time.

3. I build the recieving parts to an array and do stuff with those arrays
in the main app.

Should I try tcp ip ? Or can you give me an example of how to convert an
array into a byte and back?


(reason i do it this way, an application that is not written in vb is run )
but i made my app a front end loader. I keep track
of each process i create when running that application, and the working
directory and stuff. I found early on that just through
a process i cannot get the "working directory" which i required. So thats
how I came accross this.
If this little app closes - oh well...but its better than nothing.

Thanks for you email.

Miro
-Looks like you have used this stuff before
 
Miro said:
1. Is the receiving application a .NET application?
-Yes...its actually 1 exe... i wrote.

Great - that makes the serialization part easier...
and what I do is this:
You click on an exe...( it checks the processes to see if its already
running ) ...if it isnt,
it opens a UDP port and listens.

now lets say you run the exe agian,
the exe now realizes its already running, so it sends out
"where the exe ran from, exe arg paramaters, working diretory... "
so like 3 or 4 ( lets say 100 char in length strings ).

Once its done sending, I close the application.
So instantly the exe#1 recieves the packets in another thread, so the thread
closes.
It reopens the thread...and listens some more incase its done again.

I am using UDP cause I couldnt find a TCP/IP example...plus its really for
just the local machine.

Well, if that's the case, I would use WM_COPYDATA to send the data to
the other app. I can put together a small example if you would like...
That avoids the whole socket thing all together.
 
Miro said:
I think i found an example:
http://groups.google.de/group/microsoft.public.dotnet.languages.vb/msg/50de77ae71490a77

can you take a peek here and see if this is what im looking for?

Well, that is exactly what I'm talking about. This allows you to send
string data back and forth between two applications. So, to send an array
between two .NET applications, I would serialize the array using a binary
formatter to a memory stream and then turn the resulting binary data into a
base64 string. Then, you would send the string data to the other app which
would then reverse the process....

Here is a simple console app that converts a string array back and forth:

Option Strict On
Option Explicit On

Imports System
Imports System.IO
Imports System.Runtime.Serialization.Formatters.Binary

Module Module1

Sub Main()
Dim data1() As String = {"one", "two", "three", "four"}

Dim b64 As String = ArrayToBase64String(data1)

Dim data2 As String() = DirectCast(Base64StringToArray(b64),
String())

For Each item As String In data2
Console.WriteLine(item)
Next
End Sub

Public Function ArrayToBase64String(ByVal data As Array) As String
Dim mem As New MemoryStream()
Dim formatter As New BinaryFormatter()

Try
' serialize the array to the memory stream
formatter.Serialize(mem, data)

' return the base64 string
Return Convert.ToBase64String(mem.ToArray())
Finally

' get rid of the memory stream
mem.Dispose()
End Try

End Function

Public Function Base64StringToArray(ByVal data As String) As Array
' create a memory stream around the object data
Dim mem As New MemoryStream(Convert.FromBase64String(data))

' create a formatter
Dim formatter As New BinaryFormatter()

Try
Return DirectCast(formatter.Deserialize(mem), Array)
Finally
' clean up the memory stream
mem.Dispose()
End Try
End Function
End Module

You will want to add better error handling for production code, but this
should at least give you an idea of how this works.

HTH,
 
please note that the method that is proposed to send the data is not managed
.... and it will only run for sure on curent Windows systems

it is fine to use if :

using all managed code is not a requirment
the program will not be ported to other platforms in the future

managed solution :
A : Interprocess comunication can be done with .Net Remoting
B : File based with a filesystem watcher you can make this even event
driven, it should be possible to serialize and deserialize whatever object
between the 2 or more processes


regards

Michel Posseth [MCP]
 
Thank you,

I will take a good look at that example and try to learn something :)

I will see how i do.

Miro

Michel Posseth said:
please note that the method that is proposed to send the data is not
managed ... and it will only run for sure on curent Windows systems

it is fine to use if :

using all managed code is not a requirment
the program will not be ported to other platforms in the future

managed solution :
A : Interprocess comunication can be done with .Net Remoting
B : File based with a filesystem watcher you can make this even event
driven, it should be possible to serialize and deserialize whatever object
between the 2 or more processes


regards

Michel Posseth [MCP]
 
I am pretty new to vb... - get an idea, try to write it and learn as i go.
So saying that - I thought the filewatcher was only for specific files ?
not for processes
or some memory address position?
-Or am i understanding you wrong?


-Funny, my original post from last night didnt show here.
-So if it does show here, sorry for the double thank you post.

Thanks

Miro

Michel Posseth said:
please note that the method that is proposed to send the data is not
managed ... and it will only run for sure on curent Windows systems

it is fine to use if :

using all managed code is not a requirment
the program will not be ported to other platforms in the future

managed solution :
A : Interprocess comunication can be done with .Net Remoting
B : File based with a filesystem watcher you can make this even event
driven, it should be possible to serialize and deserialize whatever object
between the 2 or more processes


regards

Michel Posseth [MCP]
 
Michel said:
please note that the method that is proposed to send the data is not managed
... and it will only run for sure on curent Windows systems

it is fine to use if :

using all managed code is not a requirment
the program will not be ported to other platforms in the future


That's pretty much true of any Winforms app :) Not something I would
be overly concerned with at this poing, unless you plan to target Mono
or some other 3rd party runtime.

managed solution :
A : Interprocess comunication can be done with .Net Remoting

Probably overkill for this situation (as I understand it anyway), but
definately a solution.
B : File based with a filesystem watcher you can make this even event
driven, it should be possible to serialize and deserialize whatever object
between the 2 or more processes

Not a bad solution at all - but I was under the impression that the OP
didn't want to use a disk file. I figured using WM_COPYDATA was a LOT
simpler then trying to accomplish this via UDP :) The serialization
routines still apply in your approch as well, though I would of course
modify them to not wrap the byte data in a Base64 string. I would
simply read/write the binary data directly to the disk file.
 
Back
Top