|
-
Apr 10th, 2013, 04:11 PM
#1
Thread Starter
Hyperactive Member
Problem With Function to Return Array
I have a small project doing some P2P communication between a client and a server. The data stream comes in to the server, gets parsed and processed, then a I want to send the results of that back to the client. I'm using a function to do this which I want to return the results which then get passed back to the client. It kind of works but what shows back up at the client is "System.Object" and not the literal string that I was looking for.
Code:
Sub Reply2Client(ByVal Message As Object)
Client - New TcpClient("192.168.0.1"), 65535)
Dim Writer As New StreamWriter(Client.GetStream())
Writer.Write(ParseData(Message))
Writer.Flush()
End Sub
Function ParseData(ByVal vStream As Object)
Dim vWord(15)
Dim count As Integer
Dim words As Object() = vStream.Split("&")
Dim word as Object
For Each word In words
vWord(count) = Mid(word, Instr(word, "=") +1)
count = count + 1
Next
Return vWord
End Function
I've checked that the parsing is being done right and it is. But when this gets sent back to the client it appears as System.Object. I have tried this:
Code:
Return vWord(0) & vWord(1) & vWord(2)
and that appears on the client side as it should. So I think I'm close here I just want to send the entire array vWord() back to the client.
-
Apr 10th, 2013, 05:25 PM
#2
Re: Problem With Function to Return Array
As the 6-dimensional mathematics professor said to the brain surgeon, "It ain't Rocket Science!"
Reviews: "dunfiddlin likes his DataTables" - jmcilhinney
Please be aware that whilst I will read private messages (one day!) I am unlikely to reply to anything that does not contain offers of cash, fame or marriage!
-
Apr 10th, 2013, 05:38 PM
#3
Re: Problem With Function to Return Array
Why are you using Object types for what is clearly a string? You can't be splitting or calling Mid on an object, so you are getting a painless implicit conversion to string, then taking it even more painlessly back to Object. Still, it it is a string, you should call it a string.
My usual boring signature: Nothing
 
-
Apr 10th, 2013, 10:45 PM
#4
Re: Problem With Function to Return Array
You really should turn Option Strict On. You are using implicit conversions and late-binding all over the place and it's making for bad code. You should always specify a type for everything and you should specify the actual type that things are. If Message is a String then specify that. If vStream is a String the specify that. If vWord is a String array then specify that. So on and so forth. Your main issue is that just aren't using the proper types.
Secondly, don't create an array of a specific size if you don't intend to use that number of elements. In your case, you should be creating a List(Of String) and Add each String to that. At the end, you call ToArray on that and return the result.
-
Apr 10th, 2013, 10:48 PM
#5
Re: Problem With Function to Return Array
Also, in what universe does StreamWriter.Write have an overload that takes an Object array or a String array? If you have an array containing multiple Strings, exactly how do you then want to recombine them to send to the client?
-
Apr 11th, 2013, 07:07 AM
#6
Thread Starter
Hyperactive Member
Re: Problem With Function to Return Array
Thanks again. I am probably one of the sloppiest programmers around, but I have seen worse. And I'm still in a steep learning curve on this. I was using type object because the stream is made up of integers, doubles and strings. But you are right that I should format it all as string.
The data comes in over the Internet to this computer running the VB.NET program which is listening for anything on port 81. When the data arrives it's parsed and some calculations are made on it. I then need to send this data back over the net to the machine where it originated which is at hour hosting company. That's basically it. Since this is only a prototype I can post the code I'm working with.
This is the Tcp listener code.
Code:
Imports System.Net.Sockets
Imports System.Threading
Imports System.IO
Public Class Form1
Dim Listener As New TcpListener(81)
Dim Client As New TcpClient
Dim Message As String = ""
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim ListThread As New Thread(New ThreadStart(AddressOf Listening))
ListThread.Start()
End Sub
Private Sub Listening()
Listener.Start()
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Client = New TcpClient("192.168.0.2", 81)
Dim Writer As New StreamWriter(Client.GetStream())
Writer.Write(ParseData(Message))
Writer.Flush()
End Sub
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
If Listener.Pending = True Then
Message = ""
Client = Listener.AcceptTcpClient()
Dim Reader As New StreamReader(Client.GetStream())
While Reader.Peek > -1
Message = Message + Convert.ToChar(Reader.Read()).ToString
End While
ReplyIt(Message)
End If
End Sub
Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
Listener.Stop()
End Sub
Sub ReplyIt(ByVal Message As Object)
Client = New TcpClient("192.168.0.1", 81)
Dim Writer As New StreamWriter(Client.GetStream())
Writer.Write(ParseData(Message))
Writer.Flush()
End Sub
Function ParseData(ByVal vStream As Object)
Dim vWord(15) As Object
Dim count As Integer
vStream = Mid(vStream, InStr(vStream, "id="))
Dim words As Object() = vStream.Split("&")
Dim word As Object
'"C:\Temp\" & Mid(Mid(vStream, 4), 1, InStr(Mid(vStream, 4), "&") - 1) & ".txt"
For Each word In words
vWord(count) = Mid(word, InStr(word, "=") + 1)
count = count + 1
Next
Return vWord(0) & Chr(9) & vWord(1) & " x " & vWord(2)
End Function
End Class
-
Apr 11th, 2013, 08:27 AM
#7
Re: Problem With Function to Return Array
Ok, so as a first step, turn option Strict ON for the project, change the Objects to String, and possibly drop the legacy VB6 code (Mid, for example) in favor of .NET variations, such as Substring. Everything you are receiving is actually a series of bytes. You get to decide the meaning of those bytes, to a large extent. As it turns out, you are interpreting them all to be a string, whether they are string representations of numbers or not, which is fine if it works, because that means that they really are string representations of numbers (which is somewhat likely).
My usual boring signature: Nothing
 
-
Apr 11th, 2013, 08:42 AM
#8
Thread Starter
Hyperactive Member
Re: Problem With Function to Return Array
Thanks again everyone. OK, before I read Shaggy Hiker's reply I started my project from scratch again. It's cleaned up, I thought and it was working quite well. But as soon as I set Options Strict ON the error window filled up....Ooops, again my bad for not really knowing what I'm doing. So here is what I have and like I said, without Option Strict On it works well. If anyone has a better option than using a timer...I'm all ears.
Code:
Option Strict On
Imports System.Net.Sockets
Imports System.Threading
Imports System.IO
Public Class Form1
Dim Listener As New TcpListener(81)
Dim Client As New TcpClient
Dim Message As String = ""
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim ListThread As New Thread(New ThreadStart(AddressOf Listening))
ListThread.Start()
End Sub
Private Sub Listening()
Listener.Start()
End Sub
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
If Listener.Pending = True Then
Message = ""
Client = Listener.AcceptTcpClient()
Dim Reader As New StreamReader(Client.GetStream())
While Reader.Peek > -1
Message = Message + Convert.ToChar(Reader.Read()).ToString
End While
'MsgBox(Message, MsgBoxStyle.OkOnly)
'Sendit(ParseData(Message))
TextBox1.Text = TextBox1.Text & Now.ToString("ddd MM/dd/yyyy hh:mm tt ") & Chr(9) & Cstr((ParseData(Message))) & vbCrLf
End If
End Sub
Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
Listener.Stop()
End Sub
Function ParseData(ByVal Message As String) As String
Dim vWord() As String
Dim count As Integer
Message = Mid(Message, InStr(Message, "id="))
Dim words As String() = Message.Split*CChar(("&"))
Dim word As String
For Each word In words
vWord(count) = Mid(word, InStr(word, "=") + 1) <<--Object reference not set to an instance of an object
count = count + 1
Next
If vWord(11) = "1" Then vWord(10) = vWord(10) & "SS"
If vWord(12) = "1" Then vWord(10) = vWord(10) & "R"
Return vWord(0) & Chr(9) & vWord(10) & Chr(9) & vWord(1) & " x " & vWord(2)
End Function
Sub Sendit(ByVal Message As String)
Client = New TcpClient("192.168.0.2", 81)
Dim Writer As New StreamWriter(Client.GetStream())
Writer.Write(Message)
Writer.Flush()
End Sub
End Class
UPDATE: Ok, a few searches and I think I corrected the three error messages by using Cstr(), CChar(), etc... but I'm getting a strange error message about Objects again when it runs the ParseData sub. "Object reference not set to an instance of an object." It happens on the line in red above in the code. I thought I got rid of all the Objects and was typing everything as String.
2nd UPDATE: OK, all is well now. I took your advice and got rid of the MID in favor of Substring...with the other corrections, it's working now with Option Strict On. Here is the correction to the offending line of code:
Code:
vWord(count) = (word.Substring(InStr(word, "=")))
Now to try and pull of another miracle of running the data through Excel. Although most of that code is already done. Just hope I don't end up with leftover RCW's. Oh the pain of it all....I should have become a piano player in a bordello like my mother wanted me to be.
Last edited by Vladamir; Apr 11th, 2013 at 09:27 AM.
-
Apr 11th, 2013, 06:46 PM
#9
Thread Starter
Hyperactive Member
Re: Problem With Function to Return Array
Just trying to reinforce what I'm learning here about a Function returning an array. I still think I need some advice. What I want to do is to pass a string to the function which will parse it into it's parts and assemble it into an array. If I can get this to work it will be one less temporary text file I need to write.
Here is what I have so far but I don't understand the error I'm getting shown in red.
Code:
Option Strict On
Public Class Form1
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim vWord() As String
Dim Message As String = "id=7-1234567890&" & _
"field1=40&" & _
"field2=43&" & _
"field3=0&" & _
"field4=0&" & _
"field5=0&" & _
"field6=0&" & _
"field7=0&" & _
"field8=0&" & _
"field9=300&" & _
"field10=0&" & _
"field11=0&" & _
"field12=1&" & _
"field13=1&" & _
"field14=1&" & _
"field15=0"
Message = Mid(Message, InStr(Message, "id="))
vWord = CType(Doit(Message), String())
For i As Integer = 0 To vWord.Length - 1
TextBox1.Text = TextBox1.Text & vWord(i) & vbCrLf
Next
End Sub
Private Function Doit(ByVal Message As String) As Array
Dim words As String() = Message.Split(CChar("&"))
Dim word As String
Dim vWord() As String = Nothing
Dim count As Integer
For Each word In words
vWord(count) = (word.Substring(InStr(word, "="))) <<--Object reference not set to an instance of an object.
count = count + 1
Next
Return vWord
End Function
End Class
-
Apr 11th, 2013, 06:56 PM
#10
Lively Member
Re: Problem With Function to Return Array
Code:
Dim words As String() = Message.Split(CChar("&"))
Dim word As String
Dim vWord() As String = Nothing
Dim count As Integer
For Each word In words
vWord(count) = (word.Substring(InStr(word, "="))) <<--Object reference not set to an instance of an object.
count = count + 1
Next
Return vWord
This piece of code makes no sense. Dim vWord() As String = Nothing
NOTHING is NOTHING. You must replace
Code:
Dim vWord() As String = Nothing
with
Code:
Dim vWord() As String = {String.Empty}
Celebrating my one year anniversary on VBForums!
Please rate my post if it's helpful, that's all that the forums asks for!
-
Apr 11th, 2013, 07:11 PM
#11
Re: Problem With Function to Return Array
 Originally Posted by TheBilly102030
Code:
Dim words As String() = Message.Split(CChar("&"))
Dim word As String
Dim vWord() As String = Nothing
Dim count As Integer
For Each word In words
vWord(count) = (word.Substring(InStr(word, "="))) <<--Object reference not set to an instance of an object.
count = count + 1
Next
Return vWord
This piece of code makes no sense. Dim vWord() As String = Nothing
NOTHING is NOTHING. You must replace
Code:
Dim vWord() As String = Nothing
with
Code:
Dim vWord() As String = {String.Empty}
That's not going to help I'm afraid. The 'vWord' array needs to be the same length as the 'words' array, given that there is supposed to be a 1:1 correspondence between elements.
Also, the fact that the 'count' variable is being used is a perfect indication that a For Each loop is the wrong choice. It should be a For loop.
Code:
Dim upperBound As Integer = words.GetUpperBound(0)
Dim vWord(upperBound) As String
For i = 0 to upperBound
vWord(i) = (words(i).Substring(InStr(word, "=")))
Next
That's not all I'd change but it's a good start.
-
Apr 12th, 2013, 05:17 AM
#12
Thread Starter
Hyperactive Member
Re: Problem With Function to Return Array
You guys are bad to the bone. The changes made it work like I need. And as far as anything else you would recommend chaninging, please advise. I'm still eargerly learning to write efficient code. Many thanks.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|