Len Function - confusion

D

Demosthenes

this is from MSDN: "Returns an integer containing either the number of
characters in a string or the number of bytes required to store a variable."

under what circumstances does the Len function return the number of bytes to
store a variable, and how do you change that behavior to give you the length
of the string instead ?
 
A

Armin Zingler

Demosthenes said:
this is from MSDN: "Returns an integer containing either the number
of characters in a string or the number of bytes required to store a
variable."

under what circumstances does the Len function return the number of
bytes to store a variable,

If it's not a string. For example, for Integer it returns 4.
and how do you change that behavior to
give you the length of the string instead ?

Used with a String, it always returns the string's length.


Armin
 
P

Patrice

Based on the type. If this is a string this is the length of the string. For
any other type this is the length of the object in bytes...
 
B

Bruce W. Roeser

In VB.Net the Len() function is really a class method that does exactly what
it says.

For example you could write:

Dim X as Integer
Dim S as String = "This is a test"

Len(X) would return 4 (in bytes)
Len(S) would return 14 (in characters)

you could also write:

X.Length
S.Length

The previous function Len() is provided for backward compatibility for us
old VB developers. ;-)

HTH,

-bruce
 
D

Demosthenes

Is there a way to convert and object to a string so that I can get the
number of characters in the objec, rather than the length of the object in
bytes ?
 
A

Armin Zingler

Demosthenes said:
Is there a way to convert and object to a string so that I can get
the number of characters in the objec, rather than the length of the
object in bytes ?

What kind of object consists of characters other than a string?


Armin
 
D

Demosthenes

I am trying to get to the issue that I am having but I have a hard time
explaining it because of my limited knowledge of .NET but here goes.

I use a class I found on the internet, apologies to the author, I dont
remember where I got it from.

Imports System
Imports System.Net
Imports System.Net.Sockets
Imports System.Text

Public Class StateObject
Public workSocket As Socket = Nothing
Public BufferSize As Integer = 32767
Public buffer(32767) As Byte
Public sb As New StringBuilder()
End Class

Public Class SocketsClient
Public Event onConnect()
Public Event onError(ByVal Description As String)
Public Event onDataArrival(ByVal Data As Byte(), ByVal TotalBytes As
Integer)
Public Event onDisconnect()
Public Event onSendComplete(ByVal DataSize As Integer)

Private Shared response As [String] = [String].Empty
Private Shared port As Integer
Private Shared ipHostInfo As IPHostEntry = Dns.Resolve("localhost")
Private Shared ipAddress As ipAddress = ipHostInfo.AddressList(0)
Private Shared client As New Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp)

Public Sub Connect(ByVal RemoteHostName As String, ByVal RemotePort As
Integer)
Try
client = New Socket(AddressFamily.InterNetwork, SocketType.Stream,
ProtocolType.Tcp)
port = RemotePort
ipHostInfo = Dns.Resolve(RemoteHostName)
ipAddress = ipHostInfo.AddressList(0)
Dim remoteEP As New IPEndPoint(ipAddress, port)
client.BeginConnect(remoteEP, AddressOf sockConnected, client)
Catch
RaiseEvent onError(Err.Description)
Exit Sub
End Try
End Sub

Public Sub SendData(ByVal Data() As Byte)
Try
Dim byteData As Byte() = Data
client.BeginSend(byteData, 0, byteData.Length, 0, AddressOf
sockSendEnd, client)
Catch
RaiseEvent onError(Err.Description)
Exit Sub
End Try
End Sub

Public Sub Disconnect()
Try
client.Shutdown(SocketShutdown.Both)
Catch
End Try
client.Close()
End Sub

Public Function StringToBytes(ByVal Data As String) As Byte()
StringToBytes = System.Text.ASCIIEncoding.ASCII.GetBytes(Data)
End Function

Public Function BytestoString(ByVal Data As Byte()) As String
BytestoString = System.Text.ASCIIEncoding.ASCII.GetString(Data)
End Function

Private Sub sockConnected(ByVal ar As IAsyncResult)
Try
If client.Connected = False Then RaiseEvent onError("Connection
refused.") : Exit Sub
Dim state As New StateObject
state.workSocket = client
client.BeginReceive(state.buffer, 0, state.BufferSize, 0, AddressOf
sockDataArrival, state)
RaiseEvent onConnect()
Catch
RaiseEvent onError(Err.Description)
Exit Sub
End Try
End Sub

Private Sub sockDataArrival(ByVal ar As IAsyncResult)
Dim state As StateObject = CType(ar.AsyncState, StateObject)
Dim client As Socket = state.workSocket
Dim bytesRead As Integer

Try
bytesRead = client.EndReceive(ar)
Catch
RaiseEvent onError(Err.Description)
Exit Sub
End Try

Try
Dim Data() As Byte = state.buffer
'If bytesRead = 0 Then
' client.Shutdown(SocketShutdown.Both)
' client.Close()
' RaiseEvent onDisconnect()
' Exit Sub
'End If
ReDim state.buffer(32767)

client.BeginReceive(state.buffer, 0, state.BufferSize, 0, AddressOf
sockDataArrival, state)
RaiseEvent onDataArrival(Data, bytesRead)
Catch
RaiseEvent onError(Err.Description)
Exit Sub
End Try
End Sub

Private Sub sockSendEnd(ByVal ar As IAsyncResult)
Try
Dim client As Socket = CType(ar.AsyncState, Socket)
Dim bytesSent As Integer = client.EndSend(ar)
RaiseEvent onSendComplete(bytesSent)
Catch
RaiseEvent onError(Err.Description)
Exit Sub
End Try
End Sub

Public Function Connected() As Boolean
Try
Return client.Connected
Catch
RaiseEvent onError(Err.Description)
Exit Function
End Try
End Function
End Class

In my form I have. (again apologies to the original author)
Private WithEvents wsClient As New SocketsClient

#Region "Client Code"

Private Sub AT(ByVal Text As String)
'TextBox1.AppendText(Text & vbCrLf)
'TextBox1.ScrollToCaret()
End Sub

Private Sub AT2(ByVal Text As String)
'TextBox2.AppendText(Text & vbCrLf)
'TextBox2.ScrollToCaret()
End Sub

Private Sub wsClient_onConnect() Handles wsClient.onConnect
lbl_sts_message.Text = "Connected to server"
btn_send.Enabled = True
'AT2("Connected to server.")
End Sub

Private Sub wsClient_onError(ByVal Description As String) Handles
wsClient.onError
AT("Error: " & Description)
End Sub

Private Sub wsClient_onDataArrival(ByVal Data() As Byte, ByVal totBytes As
Integer) Handles wsClient.onDataArrival
Dim inData As String = wsClient.BytestoString(Data)
'populate_grid(inData)
Dim things As Integer
inData = inData.Trim
things = inData.Length
End Sub

Private Sub wsClient_onSendComplete(ByVal DataSize As Integer) Handles
wsClient.onSendComplete
End Sub
#End Region

the variable "things" for me ends up showing 32768 when I can see that the
string I am getting back is not nearly as long as that.
 
A

Armin Zingler

Demosthenes said:
I am trying to get to the issue that I am having but I have a hard
time explaining it because of my limited knowledge of .NET but here
goes.

I use a class I found on the internet, apologies to the author, I
dont remember where I got it from.


The problem is that the code ignores the number of bytes received. It
converts the whole buffer, which is 32768 bytes long ("ReDim
state.buffer(32767)"), into a string.

BTW, be aware that System.Text.Encoding.ASCII is a 7-bit encoding.


Armin
 
D

Demosthenes

Yes, what I did to correct it now was copy the byte array until I reached
zero and then stopped copying it. Yuck. I was thinking maybe there was
some sort of trim or truncate function to do it for me. I will post what I
did in case you guys see better ways to do this.

Dim inData() As Byte
Dim xx As Int32

Do Until Data(xx) = 0 '<--- Data was the bad guy with 32768 bytes
ReDim Preserve inData(xx)
inData(xx) = Data(xx)
xx += 1
Loop

Dim outData As String = wsClient.BytestoString(inData)
 
A

Armin Zingler

Demosthenes said:
Yes, what I did to correct it now was copy the byte array until I
reached zero and then stopped copying it. Yuck. I was thinking
maybe there was some sort of trim or truncate function to do it for
me. I will post what I did in case you guys see better ways to do
this.

Dim inData() As Byte
Dim xx As Int32

Do Until Data(xx) = 0 '<--- Data was the bad guy with 32768 bytes
ReDim Preserve inData(xx)
inData(xx) = Data(xx)
xx += 1
Loop

Dim outData As String = wsClient.BytestoString(inData)

Why do you think 0 terminates the data? You'd better use the argument
'totBytes' in the onDataArrival event handler. For example, inside
wsClient_onDataArrival, /instead of/ calling wsClient.BytesToString,
use

inData = System.Text.Encoding.Ascii.getstring(Data, 0, totBytes)

Are you sure that the byte array contains ASCII characters?

But, honestly, I'm not really sure that the SocketsClient class is
working correctly! (I wonder why it doesn't use the TcpClient class
and the networkstream to send/receive, but maybe there is a reason...)


Armin
 
H

Herfried K. Wagner [MVP]

Demosthenes said:
Is there a way to convert and object to a string so that I can get the
number of characters in the objec, rather than the length of the object in
bytes ?

There are different ways to do that ('CStr', '.ToString', 'Format', ...). I
suggest to describe your scenario in more detail.
 

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

Top