Jump to content
Xtreme .Net Talk

Recommended Posts

Posted

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

~Nate�

___________________________________________

Please use the [vb]/[cs] tags on posted code.

Please post solutions you find somewhere else.

Follow me on Twitter here.

  • Leaders
Posted

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

[sIGPIC]e[/sIGPIC]
Posted

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.)

~Nate�

___________________________________________

Please use the [vb]/[cs] tags on posted code.

Please post solutions you find somewhere else.

Follow me on Twitter here.

  • Leaders
Posted
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)?
[sIGPIC]e[/sIGPIC]
Posted

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.

~Nate�

___________________________________________

Please use the [vb]/[cs] tags on posted code.

Please post solutions you find somewhere else.

Follow me on Twitter here.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...