Nate Bross Posted October 19, 2006 Posted October 19, 2006 I have this code (posting the whole class for context) I am creating a collection of 'clients' each client has a received data event. If you look at the Test() sub, these are the values of the variables, and the unexpected results. First Time Called: Data() = "Test" (in byte array) str = nothing ols = Encoding.ASCII.GetString(Data) = "Test" (this part works) str = String.Concat(str, ols) = "Test" Second Time Called: Data() = "a Second Test" (in byte array) str = "Test" ols = Encoding.ASCII.GetString(Data) = "a Second Test" (this part works) str = String.Concat(str, ols) = "Test" Third Time Called: Data() = "a Third Test" (in byte array) str = "Test" ols = Encoding.ASCII.GetString(Data) = "a Third Test" (this part works) str = String.Concat(str, ols) = "Test" The variable ols has the correct value, but it never gets concatonated to the other string. No matter what I do, the String.Concat NEVER concats the second string to the first one, on any subsequent calling of the method. It ONLY works the first time. Does anyone have any sugestions or ideas to follow? Public Class Listener Dim TcpIpListener As TcpListener Dim ListenThread As Thread Dim Clients As Connections Dim str As String Public Sub New(ByVal IP As IPAddress, ByVal iPort As Integer, ByRef ClientCollection As Connections) TcpIpListener = New TcpListener(IP, iPort) Clients = ClientCollection ListenThread = New Thread(AddressOf Listen) ListenThread.Start() End Sub Sub Listen() TcpIpListener.Start() While True If TcpIpListener.Pending = True Then Dim tcpInConn As Communication.Client tcpInConn = New Communication.Client(TcpIpListener.AcceptTcpClient()) Clients.Add(tcpInConn) AddHandler tcpInConn.DataReceived, AddressOf Test End If Application.DoEvents() End While TcpIpListener.Stop() End Sub Private Sub Test(ByVal sender As Object, ByVal Data() As Byte) Dim ols As String = "" ols = Encoding.ASCII.GetString(Data) str = String.Concat(str, ols) End Sub Public ReadOnly Property S() Get Return str End Get End Property End Class Quote ~Nate� ___________________________________________ Please use the [vb]/[cs] tags on posted code. Please post solutions you find somewhere else. Follow me on Twitter here.
Leaders snarfblam Posted October 19, 2006 Leaders Posted October 19, 2006 Are you doing a debugger step through to see these values? I can't imagine why this does not work. Is is possible that each time Test() is called it is being done on a different instance of Listener? And, out of curiousity, have you tried simply using the concatenation operator (&) yet? What happens when you try a very simple test case such as: MessageBox.Show(String.Concat("Message", "Box")) And what happens if you condense Test() into: Private Sub Test(ByVal sender As Object, ByVal Data() As Byte) str &= Encoding.ASCII.GetString(Data) End Sub Quote [sIGPIC]e[/sIGPIC]
Nate Bross Posted October 20, 2006 Author Posted October 20, 2006 I tried &=, +=, and String.Concat. All with the same result. MessageBox.Show(String.Concat("Message", "Box")) Returns "MessageBox" as expected Strangly enough however, String.Concat("Message: ", Encoding.ASCII.GetString(Data)) Returns the expected data "Message : ByteArray". Additionally, the original str variable contains the first value. Is there a better way to achieve the functionaliy here? Basically what I want to do is create a general purpos server application. That accepts clients and spanws them into a new thread, whenever a client receives data I want the same method to be called. (Like an array of Winsock Controls in VB6, I understand it was only a collection in VB6, but I have been unable to achieve the same functionallity.) Quote ~Nate� ___________________________________________ Please use the [vb]/[cs] tags on posted code. Please post solutions you find somewhere else. Follow me on Twitter here.
Leaders snarfblam Posted October 20, 2006 Leaders Posted October 20, 2006 Are you positive that this method is being called on the same instance of Listener each time? Does anything change if you declare str and Test() statically (i.e. as shared)? Quote [sIGPIC]e[/sIGPIC]
Nate Bross Posted October 20, 2006 Author Posted October 20, 2006 I only have one instance of listener in the entire program. So I'm pretty confidant it's the same one every time through. When I declared str and Test as Shared, the results were exactly the same as before. Maybe there is something wrong with my 'Client' class. Imports System.Net Imports System.Net.Sockets Imports System.Text Imports system.Threading Namespace Communication Public Class Client Dim TcpIpClient As TcpClient Dim NetStream As NetworkStream Dim ReceiverThread As Thread Public Event DataReceived As DataReceivedHandler ''' <summary> ''' Creates the Object ''' </summary> ''' <param name="IP">IP Address This Client Will Connect To.</param> ''' <param name="Port">Port This Client Will Connect On.</param> ''' <param name="sOpenMessage">Message That Will Be Sent Upon Connection.</param> ''' <remarks>Connects to the IP Address on the Port Provided.</remarks> Public Sub New(ByVal IP As IPAddress, ByVal Port As Integer, Optional ByVal sOpenMessage As String = "") TcpIpClient = New TcpClient TcpIpClient.Connect(IP, Port) If TcpIpClient.Connected = True Then NetStream = TcpIpClient.GetStream() ReceiverThread = New Thread(AddressOf ProcessData) ReceiverThread.Start() End If End Sub ''' <summary> ''' Creates the Object ''' </summary> ''' <param name="ClientTCP">A TcpClient Object Already Connected.</param> ''' <remarks></remarks> Public Sub New(ByRef ClientTCP As TcpClient) TcpIpClient = ClientTCP If TcpIpClient.Connected = True Then NetStream = TcpIpClient.GetStream() ReceiverThread = New Thread(AddressOf ProcessData) ReceiverThread.Start() End If End Sub ''' <summary> ''' Creates the Object ''' </summary> ''' <param name="sIP">IP Address (Big-Endian) This Client Will Connect To.</param> ''' <param name="Port">Port This Client Will Connect On.</param> ''' <param name="sOpenMessage">Message That Will Be Sent Upon Connection.</param> ''' <remarks>Connects to the IP Address on the Port Provided.</remarks> Public Sub New(ByVal sIP As String, ByVal Port As Integer, Optional ByVal sOpenMessage As String = "") Me.New(IPAddress.Parse(sIP), Port, sOpenMessage) End Sub Public Sub ProcessData() While TcpIpClient.Connected = True If TcpIpClient.Connected = True Then ' Get the stream Dim networkStream As NetworkStream = TcpIpClient.GetStream() If networkStream.DataAvailable = True Then ' Read the stream into a byte array Dim bytes(TcpIpClient.ReceiveBufferSize) As Byte networkStream.Read(bytes, 0, CInt(TcpIpClient.ReceiveBufferSize)) RaiseEvent DataReceived(Me, bytes) End If End If End While End Sub Public Sub SendData(ByVal buff() As Byte, ByVal iOffset As Integer, ByVal iLength As Integer) If NetStream.CanRead = True And NetStream.CanWrite = True Then NetStream.Write(buff, iOffset, iLength) NetStream.Flush() End If End Sub Public Delegate Sub DataReceivedHandler(ByVal sender As Object, ByVal Data() As Byte) End Class Public Class Listener Dim TcpIpListener As TcpListener Dim ListenThread As Thread Dim Clients As Connections Shared str As String Public Sub New(ByVal IP As IPAddress, ByVal iPort As Integer, ByRef ClientCollection As Connections) TcpIpListener = New TcpListener(IP, iPort) Clients = ClientCollection ListenThread = New Thread(AddressOf Listen) ListenThread.Start() End Sub Sub Listen() TcpIpListener.Start() While True If TcpIpListener.Pending = True Then Dim tcpInConn As Communication.Client tcpInConn = New Communication.Client(TcpIpListener.AcceptTcpClient()) Clients.Add(tcpInConn) AddHandler tcpInConn.DataReceived, AddressOf Test End If Application.DoEvents() End While TcpIpListener.Stop() End Sub Public Shared Sub Test(ByVal sender As Object, ByVal Data() As Byte) str &= Encoding.ASCII.GetString(Data) MessageBox.Show(String.Concat("Message: ", Encoding.ASCII.GetString(Data))) End Sub Public ReadOnly Property S() Get Return str End Get End Property End Class End Namespace This code, is exactly the same as what I am running, I haven't stripped anything out; additionally, this (below) is the code for the Form1 that is the main (and only) form in the application. Imports System.Net Imports system.net.sockets Imports System.Text Public Class Form1 Dim tcpInConn As TcpClient Dim tcpOutConn As TcpClient Dim tcpListen As TcpListener Dim WithEvents c As Communication.Client Dim l As Communication.Listener Dim Clients As New Connections Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load End Sub Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click l = New Communication.Listener(IPAddress.Parse("127.0.0.1"), 6666, Clients) l.Listen() End Sub Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click c = New Communication.Client(IPAddress.Parse("127.0.0.1"), 6666) End Sub Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click c.SendData(Encoding.ASCII.GetBytes(TextBox2.Text), 0, TextBox2.Text.Length()) End Sub Private Sub c_DataReceived(ByVal sender As Object, ByVal Data() As Byte) Handles c.DataReceived MessageBox.Show(Encoding.ASCII.GetString(Data)) End Sub Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button4.Click TextBox1.Text = l.S End Sub End Class I know there are some unused variables, I was using them before just haven't gotten around to deleting them all yet. I don't know what other information you might need to help me out, but let me know and I'll see what I can find. Quote ~Nate� ___________________________________________ Please use the [vb]/[cs] tags on posted code. Please post solutions you find somewhere else. Follow me on Twitter here.
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.