Results 1 to 2 of 2

Thread: tcp/ip - consecutive serialized objects not deserializing. help!

  1. #1

    Thread Starter
    New Member
    Join Date
    Mar 2009
    Posts
    3

    Question tcp/ip - consecutive serialized objects not deserializing. help!

    Hi,

    This is my first post on here--I've been teaching myself VB via forums like this and MSDN for about 2 years now.

    I'm programming a computerized economics experiment, and I'm using a communications package that a guy I worked

    with developed. He and I have been going back and forth trying to figure out what the heck is going on.

    The upshot of the communications package is that there's a serializeable MQMessage class that we send back and forth, essentially just a package of an integer (Type), string (Text), and Object (Data). Most of the time, this goes according to plan.

    The problem is this: If the client receives two or more messages back-to-back, the client stops raising the MessageArrived event. (and presumably, the same would hold true for the server--I should test this, but jeez-oh-man, I've been running test after test for the last week).

    It's still connected, as on disconnect it throws the "Socket forcibly closed" exception. When it receives multiple messages sequentially, it's still receiving the data, it just never knows when the first message ends, and the buffer just keeps filling and filling. The problem seems to be that it can never successfully Deserialize the MQMessage object, and so it returns Nothing on the getCompletedMessage function and just keeps adding to the buffer (ABuffer.Length goes 1024, 2048, etc.). Any ideas on how to solve this would be GREATLY appreciated (I've been frustrated by this for a year or so, and have only recently taken upon myself to learn how the hell the TCP/IP part of this works to see if I can't find a solution.).

    Code to follow.

    --stopworth

  2. #2

    Thread Starter
    New Member
    Join Date
    Mar 2009
    Posts
    3

    Re: tcp/ip - consecutive serialized objects not deserializing. help!

    This is the server code:
    Code:
    Imports System
    Imports System.Net
    Imports System.Net.Sockets
    Imports System.Text
    Imports System.Threading
    
    Public Class MQmonitor
    
    'Delegates
    
        Public Delegate Sub MessageArrivedCallBack(ByVal Subject As Integer, ByVal message As MQMessage)
        Public Delegate Sub TextArrivedCallBack(ByVal Subject As Integer, ByVal text As String)
        Public Delegate Sub NewSubjectConnectedCallBack(ByVal Subject As Integer, ByVal UserName As String)
        Public Delegate Sub SubjectReconnectedCallBack(ByVal Subject As Integer, ByVal UserName As String)
        Public Delegate Sub SubjectDisconnectedCallBack(ByVal Subject As Integer, ByVal UserName As String)
        Public Delegate Sub Socket_ErrorCallBack(ByVal e As Exception)
    
    'Events
        Public Event MessageArrived(ByVal Subject As Integer, ByVal message As MQMessage)
        Public Event TextArrived(ByVal Subject As Integer, ByVal text As String)
        Public Event NewSubjectConnected(ByVal Subject As Integer, ByVal UserName As String)
        Public Event SubjectReconnected(ByVal Subject As Integer, ByVal UserName As String)
        Public Event SubjectDisconnected(ByVal Subject As Integer, ByVal UserName As String)
        Public Event Socket_Error(ByVal e As Exception)
    
    'Fields & Private Vars
        Private m_InitSubjectNumber As String = 101
        Private SubjectNameTable As New Hashtable
        Private StateTable As New Hashtable
        Private isExperimentStart As Boolean
        Dim m_ExpInstance As String
        Dim m_ExpName As String
        Dim m_port As Integer = "2955"
        Dim tcpListener As TcpListener
        Dim m_start As Boolean = False
        Dim allClients As ArrayList = New ArrayList()
        Dim currentID As Integer = 101
        Dim listener As Socket
    
    'Properties
      -    Public Property ExpInstance() As String 
      -    Public Property ExpName() As String
      -    Public Property Port() As Integer
      -    Public Property InitialSubjectNumber() As Integer
    
    'Public Functions
    'SendMessage(m as MQMessage, x as Integer) As Exception : Send MQMessage object m to Client with SubjectID x
    'BroadCastMessage(m as MQMessage) as Exception: Send MQMessage object m to all clients
    'OpenServer() as Exception: Sets up SubjectIDs and opens a TCPListener on m_port() 
    
    
    'Code
    
        Public Function SendMessage(ByVal msg As MQMessage, ByVal SubjectID As Integer) As Exception
            Try
                Dim state As ExpStateObject = StateTable.Item(SubjectID)
                Me.Send(state, msg)
            Catch ex As Exception
                Return ex
            End Try
            Return Nothing
        End Function
        
        Public Function BroadCastMessage(ByVal msg As MQMessage) As Exception
            Try
                Dim myEnumerator As IDictionaryEnumerator = StateTable.GetEnumerator()
                Dim state As ExpStateObject
    
                While myEnumerator.MoveNext()
                    state = myEnumerator.Value
                    Me.Send(state, msg)
                End While
    
            Catch ex As Exception
                Return ex
            End Try
            Return Nothing
        End Function
    
        Public Function OpenServer() As Exception
    
    	'Initializes the SubjectNumber (unique ID) and TCPListener and starts the TCPListener.
    
            If (m_start) Then
                Return New Exception("Queue has already been started")
            End If
    
            currentID = m_InitSubjectNumber
            m_start = True
            Dim bytes() As Byte = New [Byte](1024) {}
    
            ' Establish the local endpoint for the socket.
            ' The DNS name of the computer
            ' running the listener is "host.contoso.com".
    
    
            ' Bind the socket to the local endpoint and listen for incoming 
            ' connections.
            Try
                Dim ipHostInfo As IPHostEntry = Dns.GetHostEntry(Dns.GetHostName)
    
                Dim ipAddress As IPAddress = ipHostInfo.AddressList(0)
                For Each ip As IPAddress In ipHostInfo.AddressList
                    If (ip.AddressFamily = AddressFamily.InterNetwork) Then
                        ipAddress = ip
                        Exit For
                    End If
                Next
    
                Dim localEndPoint As New IPEndPoint(ipAddress, m_port)
    
                ' Intializes a TCP/IP socket.
                Dim listener As New Socket(AddressFamily.InterNetwork, _
                    SocketType.Stream, ProtocolType.Tcp)
    
                listener.Bind(localEndPoint)
                listener.Listen(10)
    
                ' Start an asynchronous socket to listen for connections.
                listener.BeginAccept(New AsyncCallback(AddressOf AcceptCallback), _
                listener)
    
            Catch e As Exception
                Return e
            End Try
    
            Return Nothing
        End Function
    
        Private Sub AcceptCallback(ByVal ar As IAsyncResult)
    
            ' Get the socket that handles the client request.
            Dim listener As Socket = CType(ar.AsyncState, Socket)
            Dim handler As Socket = listener.EndAccept(ar)
            handler.NoDelay = True
    
            ' Create the state object.
            Dim state As New ExpStateObject()
            state.workSocket = handler
            handler.BeginReceive(state.buffer, 0, ExpStateObject.BufferSize, 0, _
            New AsyncCallback(AddressOf ReceiveCallback), state)
            listener.BeginAccept(New AsyncCallback(AddressOf AcceptCallback), listener)
    
        End Sub 'AcceptCallback
        Private Sub ReceiveCallback(ByVal ar As IAsyncResult)
            Dim content As [String] = [String].Empty
            ' Retrieve the state object and the handler socket
            ' from the asynchronous state object.
            Dim state As ExpStateObject = CType(ar.AsyncState, ExpStateObject)
            Dim handler As Socket = state.workSocket
    
            ' Read data from client socket. 
            Try
                Dim bytesRead As Integer = handler.EndReceive(ar)
    
                If bytesRead > 0 Then
    
                    Dim message As MQMessage = state.getCompletedMessage(bytesRead)
                    
    		If Not (message Is Nothing) Then
                        messageRecieved(state, message)
                    End If
                    handler.BeginReceive(state.buffer, 0, ExpStateObject.BufferSize, _
                            0, New AsyncCallback(AddressOf ReceiveCallback), state)
    
                End If
            Catch ex As Exception
                RaiseEvent Socket_Error(ex)
            End Try
    
    
        End Sub 'ReadCallback
        Private Sub messageRecieved(ByRef state As ExpStateObject, ByVal msg As MQMessage)
            If msg.Type = MQMessage.TYPE_SUBJECT_CONNECTION_MESSAGE Then
                connectionRequest(state, msg)
            ElseIf msg.Type = MQMessage.TYPE_PLAIN_TEXT_MESSAGE Then
                RaiseEvent TextArrived(state.SubjectID, msg.Text)
            Else
                RaiseEvent MessageArrived(state.SubjectID, msg)
            End If
        End Sub
        Private Function connectionRequest(ByRef state As ExpStateObject, ByVal msg As MQMessage) As Integer
            Dim userName As String = CType(msg.Data, MQMessage.SubjectConnectionMessage).UserName
            Dim ID As Integer
    
            If isExperimentStart Then
                If SubjectNameTable.ContainsKey(userName) Then
                    ID = SubjectNameTable.Item(userName)
                    state.SubjectID = ID
                    updateStateTable(state, ID)
                    ReSendMessage(ID)
    
    
                End If
            Else
                If SubjectNameTable.ContainsKey(userName) Then
                    Send(state, New MQMessage(MQMessage.TYPE_DUPLICATE_USERNAME_MESSAGE))
                Else
                    ID = currentID
                    currentID += 1
                    state.SubjectID = ID
                    SubjectNameTable.Add(userName, ID)
                    updateStateTable(state, ID)
                    RaiseEvent NewSubjectConnected(ID, CType(msg.Data, MQMessage.SubjectConnectionMessage).UserName)
    
    
                    Dim message As New MQMessage(MQMessage.TYPE_LOGIN_CONFIRMED_MESSAGE)
                    message.Data = ID
                    Send(state, message)
    
                End If
            End If
    
        End Function 'connectionRequest
    
        Private Sub updateStateTable(ByVal state As ExpStateObject, ByVal subjectID As Integer)
            If StateTable.ContainsKey(subjectID) Then
                Dim oldState As ExpStateObject = StateTable.Item(subjectID)
                Dim socket As Socket = oldState.workSocket
                If Not (socket Is Nothing) Then
                    socket.Shutdown(SocketShutdown.Both)
                    socket.Close()
                End If
    
                StateTable.Remove(subjectID)
            End If
            StateTable.Add(subjectID, state)
        End Sub 'updateStateTable
    
        Private Sub ReSendMessage(ByVal subjectID As Integer)
            Dim state As ExpStateObject = StateTable.Item(subjectID)
            Dim msg As MQMessage
    
            Dim i As Integer
            SyncLock (state)
                For i = 0 To state.MessageQueue.Count
                    msg = state.MessageQueue.Item(i)
                    state.workSocket.Send(msg.toBytes)
                Next
            End SyncLock
    
        End Sub
    
        Private Sub Send(ByVal handler As ExpStateObject, ByVal data As MQMessage)
           'Dim byteData As Byte() = SerializeUtils.Serialize(data)
            SyncLock (handler)
                handler.MessageQueue.Add(data)
                Dim message() As Byte = data.toBytes
    
                handler.workSocket.Send(message)
    
            End SyncLock
        End Sub 'Send
    
        Public Sub startExperiment()
            isExperimentStart = True
        End Sub

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width