simonallenuk
asked on
Byte array cannot be converted to String for sending over UDP
Hi,
Basically I'm reading in a file (wav, text, jpg etc) for transfer over UDP
=============
Dim objBr As New BinaryReader(File.OpenRead (FilenameG oesHere))
Dim bytFile As Byte() = objBr.ReadBytes(objBr.Base Stream.Len gth)
objBr.Close()
xSock.UDP_Send(txtIPIn.Tex t, 10090, bytFile)
=============
Then I try to send the array (stored in bytFile) I get this message:
"Value of type '1-dimensional array of Byte' cannot be converted to 'String'."
I've tried a few different things but nothing works. I am assuming that converting a binary file to string isn't a good idea. Is there a way round this or an alternate method of sending the files using UDP rather than TCP/IP ?
Simon
Basically I'm reading in a file (wav, text, jpg etc) for transfer over UDP
=============
Dim objBr As New BinaryReader(File.OpenRead
Dim bytFile As Byte() = objBr.ReadBytes(objBr.Base
objBr.Close()
xSock.UDP_Send(txtIPIn.Tex
=============
Then I try to send the array (stored in bytFile) I get this message:
"Value of type '1-dimensional array of Byte' cannot be converted to 'String'."
I've tried a few different things but nothing works. I am assuming that converting a binary file to string isn't a good idea. Is there a way round this or an alternate method of sending the files using UDP rather than TCP/IP ?
Simon
ASKER
Oops, Its a seperate class file:
====================
#Region "Imports"
Imports System
Imports System.IO
Imports System.Net
Imports System.Net.Sockets
Imports System.Text
Imports System.Threading
#End Region
Public Class xSock
#Region "Declares"
Private Shared UDP_Client As New UdpClient
Private Shared UDP_Server_Port As Integer
Private Shared thdUdp As Thread
Private Shared UDP_Server As UdpClient
#End Region
#Region "Events"
'Public Event Close()
Public Shared Event DataArrival(ByVal Data As String)
Public Shared Event Sock_Error(ByVal Description As String)
#End Region
#Region "UDP"
Public Shared Sub UDP_Send(ByVal Host As String, ByVal Port As Integer, ByVal Data As String)
Try
UDP_Client.Connect(Host, Port)
Dim sendBytes As [Byte]() = Encoding.Unicode.GetBytes( Data)
UDP_Client.Send(sendBytes, sendBytes.Length)
Catch e As Exception
RaiseEvent Sock_Error(e.ToString)
End Try
End Sub
Public Shared Function UDP_Listen(ByVal Port As Integer) As Boolean
Try
UDP_Server_Port = Port
UDP_Server = New UdpClient(Port)
thdUdp = New Thread(AddressOf GetUDPData)
thdUdp.Start()
Catch e As Exception
RaiseEvent Sock_Error(e.ToString)
End Try
End Function
Private Shared Sub GetUDPData()
Do While True
Try
Dim RemoteIpEndPoint As New IPEndPoint(IPAddress.Any, 0)
Dim RData = Encoding.Unicode.GetString (UDP_Serve r.Receive( RemoteIpEn dPoint))
RaiseEvent DataArrival(RData)
If RData = "CloseMe" Then Exit Do
Thread.Sleep(0)
Catch e As Exception
RaiseEvent Sock_Error(e.ToString)
End Try
Loop
End Sub
Public Shared Sub CloseSock()
Dim s As New txtserver
UDP_Send(s.txtIPOut.Text, UDP_Server_Port, "CloseMe")
Thread.Sleep(30)
UDP_Server.Close()
thdUdp.Abort()
End Sub
#End Region
End Class
===================
====================
#Region "Imports"
Imports System
Imports System.IO
Imports System.Net
Imports System.Net.Sockets
Imports System.Text
Imports System.Threading
#End Region
Public Class xSock
#Region "Declares"
Private Shared UDP_Client As New UdpClient
Private Shared UDP_Server_Port As Integer
Private Shared thdUdp As Thread
Private Shared UDP_Server As UdpClient
#End Region
#Region "Events"
'Public Event Close()
Public Shared Event DataArrival(ByVal Data As String)
Public Shared Event Sock_Error(ByVal Description As String)
#End Region
#Region "UDP"
Public Shared Sub UDP_Send(ByVal Host As String, ByVal Port As Integer, ByVal Data As String)
Try
UDP_Client.Connect(Host, Port)
Dim sendBytes As [Byte]() = Encoding.Unicode.GetBytes(
UDP_Client.Send(sendBytes,
Catch e As Exception
RaiseEvent Sock_Error(e.ToString)
End Try
End Sub
Public Shared Function UDP_Listen(ByVal Port As Integer) As Boolean
Try
UDP_Server_Port = Port
UDP_Server = New UdpClient(Port)
thdUdp = New Thread(AddressOf GetUDPData)
thdUdp.Start()
Catch e As Exception
RaiseEvent Sock_Error(e.ToString)
End Try
End Function
Private Shared Sub GetUDPData()
Do While True
Try
Dim RemoteIpEndPoint As New IPEndPoint(IPAddress.Any, 0)
Dim RData = Encoding.Unicode.GetString
RaiseEvent DataArrival(RData)
If RData = "CloseMe" Then Exit Do
Thread.Sleep(0)
Catch e As Exception
RaiseEvent Sock_Error(e.ToString)
End Try
Loop
End Sub
Public Shared Sub CloseSock()
Dim s As New txtserver
UDP_Send(s.txtIPOut.Text, UDP_Server_Port, "CloseMe")
Thread.Sleep(30)
UDP_Server.Close()
thdUdp.Abort()
End Sub
#End Region
End Class
===================
In this line, you should be passing data as String, but you are passing a byte array:
Public Shared Sub UDP_Send(ByVal Host As String, ByVal Port As Integer, ByVal Data As String)
Implicit conversion are not allowed for this--you need an explicit conversion:
Dim dataString As String = Encoding.ASCII.GetString(b ytFile)
You can also use different encoding, such as Unicode, UT8, etc.
Bob
Public Shared Sub UDP_Send(ByVal Host As String, ByVal Port As Integer, ByVal Data As String)
Implicit conversion are not allowed for this--you need an explicit conversion:
Dim dataString As String = Encoding.ASCII.GetString(b
You can also use different encoding, such as Unicode, UT8, etc.
Bob
ASKER
Thanks to TheLearnedOne I can now send text files over UDP but unfortunatly I when I try doing it with .wav files they:
a) Using ASCII are the same file size but not a valid audio file
or
b) Using UTF8 are not the same file size and aren't valid audio files
Any Ideas ?
a) Using ASCII are the same file size but not a valid audio file
or
b) Using UTF8 are not the same file size and aren't valid audio files
Any Ideas ?
D'oh. Change the parameter to ByVal Data As Byte(). Then, don't convert from byte to string, just Send with the byte array, which is what the UDPClient.Send takes as a parameter anyway.
Bob
Bob
ASKER
Oh yea Unicode makes a file twice as big but doesn't work.
I have the wav file stored in a byte array... but its that array that I don't know how to transfer over UDP.
I have the wav file stored in a byte array... but its that array that I don't know how to transfer over UDP.
What I am trying to say is that you are converting back and forth from byte array to string to byte array, and that is not necessary:
UDPClient.Send:
Public Function Send(Byte(), Integer) As Integer <-- Byte array.
Just keep everything as Byte array, and do use any encoding.
Bob
UDPClient.Send:
Public Function Send(Byte(), Integer) As Integer <-- Byte array.
Just keep everything as Byte array, and do use any encoding.
Bob
ASKER
Just tried that "ByVal Data As Byte()" but i get:
'1-dimensional array of Byte' cannot be converted to 'Byte'.
'1-dimensional array of Byte' cannot be converted to 'Byte'.
Delete this line:
Dim sendBytes As [Byte]() = Encoding.Unicode.GetBytes( Data)
Also, can I see the code that you have now?
Bob
Dim sendBytes As [Byte]() = Encoding.Unicode.GetBytes(
Also, can I see the code that you have now?
Bob
ASKER
receiver:
=====
xSock.UDP_Send(txtIPIn.Tex t, 10090, dataString)
lstMsg.Items.Add(vMsg) <-- List box just so i can see whats being sent before it goes to a file
Dim fs As New IO.FileStream(txtOutput.Te xt, IO.FileMode.Create)
Dim bw As New IO.BinaryWriter(fs)
'Dim temp As Byte = Encoding.Convert(dataStrin g, bytFile)
bw.Write(vMsg)
bw.Close()
sender:
=====
Dim objBr As New BinaryReader(File.OpenRead (txtInput. Text))
Dim bytFile As Byte() = objBr.ReadBytes(objBr.Base Stream.Len gth)
objBr.Close()
xSock.UDP_Send(txtIPIn.Tex t, 10090, bytFile)
cvSock.vb
======
#Region "UDP"
Public Shared Sub UDP_Send(ByVal Host As String, ByVal Port As Integer, ByVal Data As Byte)
Try
UDP_Client.Connect(Host, Port)
'Dim sendBytes As [Byte]() = Encoding.Unicode.GetBytes( Data)
'UDP_Client.Send(sendBytes , sendBytes.Length)
<-- Unsure how to add in your code here!-->
UDPClient.Send:
Public Function Send(Byte(), Integer) As Integer <-- Byte array
<-- -- -- -- -- -- -- -- -- -- -->
Catch e As Exception
RaiseEvent Sock_Error(e.ToString)
End Try
End Sub
=====
xSock.UDP_Send(txtIPIn.Tex
lstMsg.Items.Add(vMsg) <-- List box just so i can see whats being sent before it goes to a file
Dim fs As New IO.FileStream(txtOutput.Te
Dim bw As New IO.BinaryWriter(fs)
'Dim temp As Byte = Encoding.Convert(dataStrin
bw.Write(vMsg)
bw.Close()
sender:
=====
Dim objBr As New BinaryReader(File.OpenRead
Dim bytFile As Byte() = objBr.ReadBytes(objBr.Base
objBr.Close()
xSock.UDP_Send(txtIPIn.Tex
cvSock.vb
======
#Region "UDP"
Public Shared Sub UDP_Send(ByVal Host As String, ByVal Port As Integer, ByVal Data As Byte)
Try
UDP_Client.Connect(Host, Port)
'Dim sendBytes As [Byte]() = Encoding.Unicode.GetBytes(
'UDP_Client.Send(sendBytes
<-- Unsure how to add in your code here!-->
UDPClient.Send:
Public Function Send(Byte(), Integer) As Integer <-- Byte array
<-- -- -- -- -- -- -- -- -- -- -->
Catch e As Exception
RaiseEvent Sock_Error(e.ToString)
End Try
End Sub
Public Shared Sub UDP_Send(ByVal Host As String, ByVal Port As Integer, ByVal Data As Byte())
Try
UDP_Client.Connect(Host, Port)
UDP_Client.Send(sendBytes, sendBytes.Length)
Catch e As Exception
RaiseEvent Sock_Error(e.ToString)
End Try
End Sub
Try
UDP_Client.Connect(Host, Port)
UDP_Client.Send(sendBytes,
Catch e As Exception
RaiseEvent Sock_Error(e.ToString)
End Try
End Sub
Sorry for the confusion.
Bob
Bob
ASKER
Since sendBytes is declared and using
Dim sendbytes As Byte
doesn't work for sendBytes.Length
What should I use?
Dim sendbytes As Byte
doesn't work for sendBytes.Length
What should I use?
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Ok nearly there
In the cvSock.vb file there is a section:
Public Shared Sub CloseSock()
Dim s As New txtserver
UDP_Send(s.txtIPOut.Text, UDP_Server_Port, "CloseMe")
Thread.Sleep(30)
UDP_Server.Close()
thdUdp.Abort()
End Sub
Instead of "CloseME" which is a string what can I put in there! as its now suppose to be a byte array.
In the cvSock.vb file there is a section:
Public Shared Sub CloseSock()
Dim s As New txtserver
UDP_Send(s.txtIPOut.Text, UDP_Server_Port, "CloseMe")
Thread.Sleep(30)
UDP_Server.Close()
thdUdp.Abort()
End Sub
Instead of "CloseME" which is a string what can I put in there! as its now suppose to be a byte array.
You had something close before:
Dim bytClose() As Byte = System.Text.Encoding.Ascii Encoding.G etBytes("C loseMe")
UDPSend(s.txtIPOut.Text, UDP_Server_Port, bytClose)
Dim bytClose() As Byte = System.Text.Encoding.Ascii
UDPSend(s.txtIPOut.Text, UDP_Server_Port, bytClose)
ASKER
After some changes to other code I have the program will compile but the input/output from the files transfered look like this, even with plain text files:
瑨ç´â¼ºçœ¯ç·æ”®ç¸ç‰¥ç ´æ”æ¸æ… ¨æ®
瑨ç´â¼ºçœ¯ç·æ”®ç¸ç‰¥ç
You can use overloads for the same routine name. Therefore keep both routines:
Public Shared Sub UDP_Send(ByVal Host As String, ByVal Port As Integer, ByVal Data As String)
and
Public Shared Sub UDP_Send(ByVal Host As String, ByVal Port As Integer, ByVal Data As Byte())
then you can easily call both:
UDP_Send(s.txtIPOut.Text, UDP_Server_Port, "CloseMe")
and
xSock.UDP_Send(txtIPIn.Tex t, 10090, bytFile)
and you don't need to do any additional encoding.
--- --- ---
The receiving end is using Unicode encoding (to decode):
Dim RData = Encoding.Unicode.GetString (UDP_Serve r.Receive( RemoteIpEn dPoint))
RaiseEvent DataArrival(RData)
If RData = "CloseMe" Then Exit Do
Therefore you MUST use Unicode encoding when sending the "CloseMe", otherwise it'll never know when it's the end of the data. (P.S. I'd call that a bug anyway. Just try sending some real data that's the string "CloseMe" and your server will prematurely terminate reception.)
After that, you'll need to put your debugging skills to work.
--- --- ---
Here's a little snippet that might be handy. (It could use lots of improvement/extensions,too .)
Function BytesToString(ByVal bytes As Byte(), Optional ByVal AsHex As Boolean = True) As String
Dim sb As New System.Text.StringBuilder
Dim sw As New System.IO.StringWriter(sb)
Dim nl As String = System.Environment.NewLine
Dim count As Integer = 0
Dim blockSize As Integer = 16
Dim blockFormat As String
Dim itemFormat As String
If AsHex Then
blockFormat = "{0:X4}: "
itemFormat = " {0:X2}"
Else
blockFormat = "{0,5}: "
itemFormat = " {0,3}"
End If
For blockStart As Integer = 0 To bytes.Length Step blockSize
sw.Write(String.Format(blo ckFormat, blockStart))
For index As Integer = blockStart To blockStart + blockSize - 1
If index < bytes.Length Then
sw.Write(String.Format(ite mFormat, bytes(index)))
End If
Next
sw.WriteLine()
Next
Return sw.ToString
End Function
Sample Output:
0000: 48 00 65 00 6C 00 6C 00 6F 00 2C 00 20 00 74 00
0010: 68 00 65 00 72 00 65 00 21 00 20 00 20 00 41 00
0020: 42 00 43 00 44 00 45 00 46 00 47 00 48 00 49 00
0030: 4A 00 4B 00 4C 00 4D 00 4E 00 4F 00 50 00 51 00
0040: 52 00 53 00 54 00 55 00 56 00 57 00 58 00 59 00
0050: 5A 00
Public Shared Sub UDP_Send(ByVal Host As String, ByVal Port As Integer, ByVal Data As String)
and
Public Shared Sub UDP_Send(ByVal Host As String, ByVal Port As Integer, ByVal Data As Byte())
then you can easily call both:
UDP_Send(s.txtIPOut.Text, UDP_Server_Port, "CloseMe")
and
xSock.UDP_Send(txtIPIn.Tex
and you don't need to do any additional encoding.
--- --- ---
The receiving end is using Unicode encoding (to decode):
Dim RData = Encoding.Unicode.GetString
RaiseEvent DataArrival(RData)
If RData = "CloseMe" Then Exit Do
Therefore you MUST use Unicode encoding when sending the "CloseMe", otherwise it'll never know when it's the end of the data. (P.S. I'd call that a bug anyway. Just try sending some real data that's the string "CloseMe" and your server will prematurely terminate reception.)
After that, you'll need to put your debugging skills to work.
--- --- ---
Here's a little snippet that might be handy. (It could use lots of improvement/extensions,too
Function BytesToString(ByVal bytes As Byte(), Optional ByVal AsHex As Boolean = True) As String
Dim sb As New System.Text.StringBuilder
Dim sw As New System.IO.StringWriter(sb)
Dim nl As String = System.Environment.NewLine
Dim count As Integer = 0
Dim blockSize As Integer = 16
Dim blockFormat As String
Dim itemFormat As String
If AsHex Then
blockFormat = "{0:X4}: "
itemFormat = " {0:X2}"
Else
blockFormat = "{0,5}: "
itemFormat = " {0,3}"
End If
For blockStart As Integer = 0 To bytes.Length Step blockSize
sw.Write(String.Format(blo
For index As Integer = blockStart To blockStart + blockSize - 1
If index < bytes.Length Then
sw.Write(String.Format(ite
End If
Next
sw.WriteLine()
Next
Return sw.ToString
End Function
Sample Output:
0000: 48 00 65 00 6C 00 6C 00 6F 00 2C 00 20 00 74 00
0010: 68 00 65 00 72 00 65 00 21 00 20 00 20 00 41 00
0020: 42 00 43 00 44 00 45 00 46 00 47 00 48 00 49 00
0030: 4A 00 4B 00 4C 00 4D 00 4E 00 4F 00 50 00 51 00
0040: 52 00 53 00 54 00 55 00 56 00 57 00 58 00 59 00
0050: 5A 00
Also, you'll want to rewrite GetUDPData() because it's decoding right away, so all your nice unencoded bytes are immediately being decoded. That's not what you want. Since they were never encoded, you get garbage. I suggest something like this:
Private Shared Sub GetUDPData()
Do While True
Try
Dim RemoteIpEndPoint As New IPEndPoint(IPAddress.Any, 0)
Dim RBytes As Byte() = UDP_Server.Receive(RemoteI pEndPoint)
Dim RData = Encoding.Unicode.GetString (RBytes)
RaiseEvent DataArrivalBytes(RBytes)
RaiseEvent DataArrival(RData)
If RData = "CloseMe" Then Exit Do
Thread.Sleep(0)
Catch e As Exception
RaiseEvent Sock_Error(e.ToString)
End Try
Loop
End Sub
Then you'll also need to write the new DataArrivalBytes event,too. Then use the DataArrivalBytes event if you want to receive the undecoded bytes, or the DataArrival event if you want to receive a text string.
Private Shared Sub GetUDPData()
Do While True
Try
Dim RemoteIpEndPoint As New IPEndPoint(IPAddress.Any, 0)
Dim RBytes As Byte() = UDP_Server.Receive(RemoteI
Dim RData = Encoding.Unicode.GetString
RaiseEvent DataArrivalBytes(RBytes)
RaiseEvent DataArrival(RData)
If RData = "CloseMe" Then Exit Do
Thread.Sleep(0)
Catch e As Exception
RaiseEvent Sock_Error(e.ToString)
End Try
Loop
End Sub
Then you'll also need to write the new DataArrivalBytes event,too. Then use the DataArrivalBytes event if you want to receive the undecoded bytes, or the DataArrival event if you want to receive a text string.
And out of the blue, streaking across the sky is Super man, come to save the day *GRIN*
You'd better watch out, Big Bad Bill is back in town. Howdy stranger :)
Bob
You'd better watch out, Big Bad Bill is back in town. Howdy stranger :)
Bob
ASKER
Maybe its the cold I have or just my stupidty but my heads starting to spin with all this code.
ASKER
The function 'BytesToString'... were does this fit in the grand scheme of things?
BytesToString would be useful for debugging to see what the actual bytes transferred are.
You said it was: 瑨ç´â¼ºçœ¯ç·æ”®ç¸ç‰¥ç ´æ”æ¸æ… ¨æ®, but that's pretty meaningless, at least to me. BytesToString would show the actual values (represented as hex or decimal) of the bytes. You could use it as:
Debug.Write(BytesToString( Data ))
or use it to write to a log file.
If you made log files on both your client (sending) and your server (receiving), you should then be able to examine the logs and hopefully find some correlation between the two, if the data transfer is not working. If the data transfer is working, you would expect identical results on both ends.
I have a slightly improved version of BytesToString that also prints the decoded string to right of the list of bytes. Do you want it? Output would look like this for Hex and Unicode encoding.
0000: 48 00 65 00 6C 00 6C 00 6F 00 2C 00 20 00 74 00 - Hello, t
0010: 68 00 65 00 72 00 65 00 21 00 - here!
[ Knowing nothing about your programming knowledge, I ask ... ] How are your debugging skills? Are you familiar with setting/clearing breakpoints, stepping through code line by line, using watchpoints, and using the Command window?
> Maybe its the cold ...
Aaaah, shake it off. We can slow down and go step by step. Just keep asking clarifying questions. I'm a bit tired and fuzzy-headed myself tonight.
Oh Great TheLearnedOne: I didn't mean to hijack the question, but I thought the "overloads" issue would really clear up some things. (And was surprised you hadn't mentioned it yet. I was thinking you were just tired that day.) Then I had another idea, and another ... Thanks for the welcome back.
You said it was: 瑨ç´â¼ºçœ¯ç·æ”®ç¸ç‰¥ç
Debug.Write(BytesToString(
or use it to write to a log file.
If you made log files on both your client (sending) and your server (receiving), you should then be able to examine the logs and hopefully find some correlation between the two, if the data transfer is not working. If the data transfer is working, you would expect identical results on both ends.
I have a slightly improved version of BytesToString that also prints the decoded string to right of the list of bytes. Do you want it? Output would look like this for Hex and Unicode encoding.
0000: 48 00 65 00 6C 00 6C 00 6F 00 2C 00 20 00 74 00 - Hello, t
0010: 68 00 65 00 72 00 65 00 21 00 - here!
[ Knowing nothing about your programming knowledge, I ask ... ] How are your debugging skills? Are you familiar with setting/clearing breakpoints, stepping through code line by line, using watchpoints, and using the Command window?
> Maybe its the cold ...
Aaaah, shake it off. We can slow down and go step by step. Just keep asking clarifying questions. I'm a bit tired and fuzzy-headed myself tonight.
Oh Great TheLearnedOne: I didn't mean to hijack the question, but I thought the "overloads" issue would really clear up some things. (And was surprised you hadn't mentioned it yet. I was thinking you were just tired that day.) Then I had another idea, and another ... Thanks for the welcome back.
ASKER
My debugging skills are pretty much average.
This is the output (first 10 lines only) for sending a small wav file,
the receiver had only half of the total lines from the sender:
Sender:
=====
0000: 52 49 46 46 F6 44 00 00 57 41 56 45 66 6D 74 20
0010: 10 00 00 00 01 00 01 00 80 BB 00 00 80 BB 00 00
0020: 01 00 08 00 64 61 74 61 D1 44 00 00 7F 7F 7F 7F
0030: 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F
0040: 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F
0050: 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F
0060: 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F
0070: 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F
0080: 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F
0090: 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F
Receiver:
======
0000: 3F 3F 3F 00 3F 3F 3F 3F 10 00 01 01 3F 00 3F 00
0010: 01 08 3F 3F 3F 00 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F
0020: 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F
0030: 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F
0040: 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F
0050: 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F
0060: 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F
0070: 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F
0080: 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F
0090: 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F
What I did notice was the client that gets the file is looking for string values (before I added in the 2nd last line)
Private Sub OnDataRival(ByVal vMsg As String)
lstMsg.Items.Add(vMsg)
Dim fs As New IO.FileStream(txtOutput.Te xt, IO.FileMode.Create)
Dim bw As New IO.BinaryWriter(fs)
bw.Write(vMsg)
bw.Close()
'-- check output directly after reading in
Dim msgdata() As Byte = System.Text.Encoding.ASCII .GetBytes( vMsg)
Debug.Write(BytesToString( msgdata))
This is the output (first 10 lines only) for sending a small wav file,
the receiver had only half of the total lines from the sender:
Sender:
=====
0000: 52 49 46 46 F6 44 00 00 57 41 56 45 66 6D 74 20
0010: 10 00 00 00 01 00 01 00 80 BB 00 00 80 BB 00 00
0020: 01 00 08 00 64 61 74 61 D1 44 00 00 7F 7F 7F 7F
0030: 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F
0040: 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F
0050: 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F
0060: 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F
0070: 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F
0080: 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F
0090: 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F
Receiver:
======
0000: 3F 3F 3F 00 3F 3F 3F 3F 10 00 01 01 3F 00 3F 00
0010: 01 08 3F 3F 3F 00 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F
0020: 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F
0030: 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F
0040: 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F
0050: 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F
0060: 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F
0070: 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F
0080: 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F
0090: 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F
What I did notice was the client that gets the file is looking for string values (before I added in the 2nd last line)
Private Sub OnDataRival(ByVal vMsg As String)
lstMsg.Items.Add(vMsg)
Dim fs As New IO.FileStream(txtOutput.Te
Dim bw As New IO.BinaryWriter(fs)
bw.Write(vMsg)
bw.Close()
'-- check output directly after reading in
Dim msgdata() As Byte = System.Text.Encoding.ASCII
Debug.Write(BytesToString(
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
> the receiver had only half of the total lines from the sender
Unicode is a double-byte encoding. Therefore this (almost certainly) indicates there's some mismatch with encoding.
And yep, there it is. Your second-to-last line is doing ASCII encoding.
Try just changing it to Unicode encoding.
[Theory]
Think of this whole data transmission process in the shape of a "U". The sender goes down the left-hand edge, the data
goes across the wire along the bottom. and the receiver gets the data and goes up the right-hand edge. Any actions
that the sender does (down the left) must be EXACTLY reversed by the receiver (up the right). So in general, for any
transmission process, if the sender performs processes A, B, C, then D to put the data on the wire, then the sender
must exactly reverse that: D', C', B', and finally A'.
In Out
A A'
B B'
C C'
D D'
===>
In your case, you want to send RAW UNCHANGED data bytes, so you want to avoid encoding and avoid Strings. This
actually makes things simpler. You can think of this as skipping steps B and C (and therefore also C' and B').
A: Read data bytes directly from file into byte array.
D: Send raw bytes.
---=== across the wire ===---
D': Receive raw bytes in a byte array.
A': Store raw bytes from byte array to file.
Part of your problem is that the code you're starting with (UPD_Send and GetUDPData) are designed to send strings, not
raw bytes, so they're doing encoding that you don't need or want. The key thing is you need to write replacements that
DO NO ENCODING AND NO DECODING. They just use raw bytes in a byte array.
Definition: Raw -- [In this context] unchanged, unprocessed, with no additional information or processsing
http://www.google.com/search?hl=en&q=define%3Araw
... So ...
[Implementation]
Process A: Read data bytes directly from file into byte array.
[your posted code]
Dim objBr As New BinaryReader(File.OpenRead (txtInput. Text))
Dim bytFile As Byte() = objBr.ReadBytes(objBr.Base Stream.Len gth)
objBr.Close()
Process D: Send raw bytes.
xSock.UDP_Send(txtIPIn.Tex t, 10090, bytFile) ' from your post above.
xSock.UDP_Send(txtIPIn.Tex t, 10090, "CloseMe") ' from farsight.
This uses TheLearnedOne's posted code for UDP_Send to send raw bytes, as well as your original UDP_Send to send the
Unicode-encoded termination string, which is expected and necessary for GetUDPData to properly terminate.
[TheLearnedOne's posted code]
Public Shared Sub UDP_Send(ByVal Host As String, ByVal Port As Integer, ByVal Data As Byte())
Try
UDP_Client.Connect(Host, Port)
UDP_Client.Send(sendBytes, sendBytes.Length)
Catch e As Exception
RaiseEvent Sock_Error(e.ToString)
End Try
End Sub
[From your original code]
Public Shared Sub UDP_Send(ByVal Host As String, ByVal Port As Integer, ByVal Data As String)
Try
UDP_Client.Connect(Host, Port)
Dim sendBytes As [Byte]() = Encoding.Unicode.GetBytes( Data)
UDP_Client.Send(sendBytes, sendBytes.Length)
Catch e As Exception
RaiseEvent Sock_Error(e.ToString)
End Try
End Sub
Process D': Receive raw bytes in a byte array.
[from farsight's posted code]
Private Shared Sub GetUDPData()
Do While True
Try
Dim RemoteIpEndPoint As New IPEndPoint(IPAddress.Any, 0)
Dim RBytes As Byte() = UDP_Server.Receive(RemoteI pEndPoint)
Dim RData = Encoding.Unicode.GetString (RBytes)
RaiseEvent DataArrivalBytes(RBytes)
'NOTE: I added this call to BytesToString, which at this point
'should be EXACTLY what was sent by the sender.
'Since it was NOT encoded on the sender, we'll use ASCII encoding here,
'only so we can see the first few bytes we expect in a *.WAV file: "RIFF".
Debug.WriteLine( BytesToString( RBytes, True, System.Text.Encoding.ASCII ))
RaiseEvent DataArrival(RData)
If RData = "CloseMe" Then Exit Do
Thread.Sleep(0)
Catch e As Exception
RaiseEvent Sock_Error(e.ToString)
End Try
Loop
End Sub
Process A': Store raw bytes from byte array to file.
[NOT WORKING: your most-recently posted code]
'NOTE: I corrected an apparent typo: OnDataRival ==> OnDataArrival
Private Sub OnDataArrival(ByVal vMsg As String)
lstMsg.Items.Add(vMsg)
Dim fs As New IO.FileStream(txtOutput.Te xt, IO.FileMode.Create)
Dim bw As New IO.BinaryWriter(fs)
bw.Write(vMsg)
bw.Close()
'-- check output directly after reading in
'NOTE: I changed from ASCII to Unicode encoding.
Dim msgdata() As Byte = System.Text.Encoding.Unico de.GetByte s(vMsg)
Debug.Write(BytesToString( msgdata))
End Sub
This is not working primarily because you're processing the String which is provided by the DataArrival Event, which
has already been Unicode-decoded in GetUDPData. It's got encoding we dont' need or want.
[What's remaining to do ...]
You need to add a new event that gives you the raw bytes instead of the string. In other words, implement the code for
DataArrivalBytes. Add this near the top of the xSock class (near DataArrival):
Public Shared Event DataArrivalBytes(ByVal bytes As Byte())
Delete your OnDataArrival routine, and put this instead:
Private Sub OnDataArrivalBytes(ByVal bytes As Byte())
'NOTE: Seems like a bug to add the bytes of the *wav file to a listbox ... so don't.
'Currently we're sending only the file, but NOT the file name.
'lstMsg.Items.Add(vMsg)
Dim fs As New IO.FileStream(txtOutput.Te xt, IO.FileMode.Create)
Dim bw As New IO.BinaryWriter(fs)
bw.Write(bytes)
bw.Close()
'-- check output directly after reading in
'NOTE: This should write exactly the same thing that was
' written in GetUDPData
Debug.WriteLine( BytesToString( RBytes, True, System.Text.Encoding.ASCII ))
End Sub
And in the Form_Load (or other initialiation) routine, add:
AddHandler xSock.DataArrival, AddressOf OnDataArrivalBytes
and remove:
AddHandler xSock.DataArrival, AddressOf OnDataRival
---
For Reference:
It appears the original UDP code is from:
http://www.codeproject.com/Purgatory/The_UDP_under_VBNET.asp
Unicode is a double-byte encoding. Therefore this (almost certainly) indicates there's some mismatch with encoding.
And yep, there it is. Your second-to-last line is doing ASCII encoding.
Try just changing it to Unicode encoding.
[Theory]
Think of this whole data transmission process in the shape of a "U". The sender goes down the left-hand edge, the data
goes across the wire along the bottom. and the receiver gets the data and goes up the right-hand edge. Any actions
that the sender does (down the left) must be EXACTLY reversed by the receiver (up the right). So in general, for any
transmission process, if the sender performs processes A, B, C, then D to put the data on the wire, then the sender
must exactly reverse that: D', C', B', and finally A'.
In Out
A A'
B B'
C C'
D D'
===>
In your case, you want to send RAW UNCHANGED data bytes, so you want to avoid encoding and avoid Strings. This
actually makes things simpler. You can think of this as skipping steps B and C (and therefore also C' and B').
A: Read data bytes directly from file into byte array.
D: Send raw bytes.
---=== across the wire ===---
D': Receive raw bytes in a byte array.
A': Store raw bytes from byte array to file.
Part of your problem is that the code you're starting with (UPD_Send and GetUDPData) are designed to send strings, not
raw bytes, so they're doing encoding that you don't need or want. The key thing is you need to write replacements that
DO NO ENCODING AND NO DECODING. They just use raw bytes in a byte array.
Definition: Raw -- [In this context] unchanged, unprocessed, with no additional information or processsing
http://www.google.com/search?hl=en&q=define%3Araw
... So ...
[Implementation]
Process A: Read data bytes directly from file into byte array.
[your posted code]
Dim objBr As New BinaryReader(File.OpenRead
Dim bytFile As Byte() = objBr.ReadBytes(objBr.Base
objBr.Close()
Process D: Send raw bytes.
xSock.UDP_Send(txtIPIn.Tex
xSock.UDP_Send(txtIPIn.Tex
This uses TheLearnedOne's posted code for UDP_Send to send raw bytes, as well as your original UDP_Send to send the
Unicode-encoded termination string, which is expected and necessary for GetUDPData to properly terminate.
[TheLearnedOne's posted code]
Public Shared Sub UDP_Send(ByVal Host As String, ByVal Port As Integer, ByVal Data As Byte())
Try
UDP_Client.Connect(Host, Port)
UDP_Client.Send(sendBytes,
Catch e As Exception
RaiseEvent Sock_Error(e.ToString)
End Try
End Sub
[From your original code]
Public Shared Sub UDP_Send(ByVal Host As String, ByVal Port As Integer, ByVal Data As String)
Try
UDP_Client.Connect(Host, Port)
Dim sendBytes As [Byte]() = Encoding.Unicode.GetBytes(
UDP_Client.Send(sendBytes,
Catch e As Exception
RaiseEvent Sock_Error(e.ToString)
End Try
End Sub
Process D': Receive raw bytes in a byte array.
[from farsight's posted code]
Private Shared Sub GetUDPData()
Do While True
Try
Dim RemoteIpEndPoint As New IPEndPoint(IPAddress.Any, 0)
Dim RBytes As Byte() = UDP_Server.Receive(RemoteI
Dim RData = Encoding.Unicode.GetString
RaiseEvent DataArrivalBytes(RBytes)
'NOTE: I added this call to BytesToString, which at this point
'should be EXACTLY what was sent by the sender.
'Since it was NOT encoded on the sender, we'll use ASCII encoding here,
'only so we can see the first few bytes we expect in a *.WAV file: "RIFF".
Debug.WriteLine( BytesToString( RBytes, True, System.Text.Encoding.ASCII
RaiseEvent DataArrival(RData)
If RData = "CloseMe" Then Exit Do
Thread.Sleep(0)
Catch e As Exception
RaiseEvent Sock_Error(e.ToString)
End Try
Loop
End Sub
Process A': Store raw bytes from byte array to file.
[NOT WORKING: your most-recently posted code]
'NOTE: I corrected an apparent typo: OnDataRival ==> OnDataArrival
Private Sub OnDataArrival(ByVal vMsg As String)
lstMsg.Items.Add(vMsg)
Dim fs As New IO.FileStream(txtOutput.Te
Dim bw As New IO.BinaryWriter(fs)
bw.Write(vMsg)
bw.Close()
'-- check output directly after reading in
'NOTE: I changed from ASCII to Unicode encoding.
Dim msgdata() As Byte = System.Text.Encoding.Unico
Debug.Write(BytesToString(
End Sub
This is not working primarily because you're processing the String which is provided by the DataArrival Event, which
has already been Unicode-decoded in GetUDPData. It's got encoding we dont' need or want.
[What's remaining to do ...]
You need to add a new event that gives you the raw bytes instead of the string. In other words, implement the code for
DataArrivalBytes. Add this near the top of the xSock class (near DataArrival):
Public Shared Event DataArrivalBytes(ByVal bytes As Byte())
Delete your OnDataArrival routine, and put this instead:
Private Sub OnDataArrivalBytes(ByVal bytes As Byte())
'NOTE: Seems like a bug to add the bytes of the *wav file to a listbox ... so don't.
'Currently we're sending only the file, but NOT the file name.
'lstMsg.Items.Add(vMsg)
Dim fs As New IO.FileStream(txtOutput.Te
Dim bw As New IO.BinaryWriter(fs)
bw.Write(bytes)
bw.Close()
'-- check output directly after reading in
'NOTE: This should write exactly the same thing that was
' written in GetUDPData
Debug.WriteLine( BytesToString( RBytes, True, System.Text.Encoding.ASCII
End Sub
And in the Form_Load (or other initialiation) routine, add:
AddHandler xSock.DataArrival, AddressOf OnDataArrivalBytes
and remove:
AddHandler xSock.DataArrival, AddressOf OnDataRival
---
For Reference:
It appears the original UDP code is from:
http://www.codeproject.com/Purgatory/The_UDP_under_VBNET.asp
Oops, that last part should be:
And in the Form_Load (or other initialiation) routine, add:
AddHandler xSock.DataArrivalBytes, AddressOf OnDataArrivalBytes ' *** changed this line ***
and remove:
AddHandler xSock.DataArrival, AddressOf OnDataRival
And in the Form_Load (or other initialiation) routine, add:
AddHandler xSock.DataArrivalBytes, AddressOf OnDataArrivalBytes ' *** changed this line ***
and remove:
AddHandler xSock.DataArrival, AddressOf OnDataRival
ASKER
========================== ========== ====
Private Sub btnSend_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSend.Click
Dim objBr As New BinaryReader(File.OpenRead (txtInput. Text))
Dim bytFile As Byte() = objBr.ReadBytes(objBr.Base Stream.Len gth)
objBr.Close()
Debug.WriteLine(BytesToStr ing(bytFil e))
xSock.UDP_Send(txtIPIn.Tex t, 10090, bytFile) <------
xSock.UDP_Send(txtIPIn.Tex t, 10090, "CloseMe")
========================== ========== ====
Ok I think i've got everything back in now... But i'm back to getting the compile error on "bytFile" saying:
Value of type '1-dimensional array of Byte' cannot be converted to 'String.
To see what I have so far: http://www.lackofpotatoes.co.uk/VB.rar
Private Sub btnSend_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSend.Click
Dim objBr As New BinaryReader(File.OpenRead
Dim bytFile As Byte() = objBr.ReadBytes(objBr.Base
objBr.Close()
Debug.WriteLine(BytesToStr
xSock.UDP_Send(txtIPIn.Tex
xSock.UDP_Send(txtIPIn.Tex
==========================
Ok I think i've got everything back in now... But i'm back to getting the compile error on "bytFile" saying:
Value of type '1-dimensional array of Byte' cannot be converted to 'String.
To see what I have so far: http://www.lackofpotatoes.co.uk/VB.rar
Hello,
I am trying to receive data over UDP sent from a Linux box. the following is the structure I am trying to recover from the received data. How do I do that? Any help is greatly appreciated.
Struct Position
{
double px;
double py;
double pz;
};
I am trying to receive data over UDP sent from a Linux box. the following is the structure I am trying to recover from the received data. How do I do that? Any help is greatly appreciated.
Struct Position
{
double px;
double py;
double pz;
};
Ashali,
Experts Exchange is all about question and answer pairs, not extended discussions. This question has already been asked and answered. Only the people who've commented in this question, and are still subscribed to it, will even notice you mentioned something.
Please create a new question and ask your question.
If needed, you can put a link to this question as related information.
Everyone reads the new questions, so you'll get the attention you need.
Experts Exchange is all about question and answer pairs, not extended discussions. This question has already been asked and answered. Only the people who've commented in this question, and are still subscribed to it, will even notice you mentioned something.
Please create a new question and ask your question.
If needed, you can put a link to this question as related information.
Everyone reads the new questions, so you'll get the attention you need.
Bob