Thread Problems – Strange Loop behavior

I have a loop inside a threaded sub and inside this loop is a simple check that one Boolean is true and another is false, if so it will append some text to a string builder.

This loop is an incoming E-Mail from a socket (hence the thread) which was connected and then threaded. Now the loop works fine apart from where it appends to the string builder (i have tried a normal string also but it the same).

Now this loop accepts packets from port 25 and sends them onto our Exchange server. Collects what exchange sends back and forwards them on to the SMTP client forming a SMTP filter. I no for a fact the loop is working because the E-Mails arrive perfectly that pass through the filter.

This is the code that does not run every time the loop runs

If SendingData And Not DataMessage Then

contentString.Append(SMTPMessage)

End If

The contentString misses random amounts of text and i can't for the life of me work out why or how the code would not be ran or if it is being ran why all the SMTPMessages don’t make it to the string. Also just to throw another spanner in the works, it does not do this all the time! some times we will run it (sending exactly the same E-Mail from our test SMTP Client) and it works fine....

Below is the complete Sub which is threaded.

Private Sub CreateListeningThread()

'' Our Connection to the SMTP Client

Dim currentSocket As Socket

'' Our Connection to the Exchange Server

Dim ExchangeSocket As New TcpClient

'' The location of the exchange server

Dim exchangeEndPoint As New IPEndPoint(IPAddress.Parse("192.168.111.7"), 25)

'' Save The Messages we get back from the two connections

Dim SMTPMessage As String

'' The Message buffer we use to receive the messages from the connections

Dim ArriveArray(2048) As Byte

'' The Message buffer we use to send messages to the connections

Dim SendArray() As Byte

'' For The total bytes of information we received.

Dim infoRecieved As Integer

'' Used for E-Mail Body

Dim DataMessage As Boolean = False

Dim SendingData As Boolean = False

Dim FirstDataPacket As Boolean = False

Dim contentString As New StringBuilder

Try

'' Open Our Connection to the exchange server.

ExchangeSocket.Connect(exchangeEndPoint)

'' The total bytes of information we received.

infoRecieved = ExchangeSocket.Client.Receive(ArriveArray)

'' Set our current connection to the connection we established from StartListening()

currentSocket = newSocket

'' Save the Connection Ready Message from the Exchange server.

SMTPMessage = Encoding.ASCII.GetString(ArriveArray)

'' Get rid of all the trailing empty chars from the buffer that the message did not use

'' and split the message back up into a new byte array.

SendArray = Encoding.ASCII.GetBytes(Replace(SMTPMessage, Chr(0), "").ToCharArray())

'' Send the Message to the SMTP client.

currentSocket.Send(SendArray, SendArray.Length, 0)

While (True)

'' Get the next message from the SMTP Client and forward it onto the

'' Exchange server.

ReDim ArriveArray(2048)

infoRecieved = currentSocket.Receive(ArriveArray)

SMTPMessage = Encoding.ASCII.GetString(ArriveArray)

If LCase(SMTPMessage).StartsWith("data") Then

DataMessage = True

SendingData = True

End If

If SendingData And Not DataMessage Then

contentString.Append(SMTPMessage)

End If

If InStr(SMTPMessage, CrLf & "." & CrLf) Then

DataMessage = False

SendingData = False

End If

SendArray = Encoding.ASCII.GetBytes(Replace(SMTPMessage, Chr(0), "").ToCharArray())

ExchangeSocket.Client.Send(SendArray, SendArray.Length, 0)

'' Get the return message from the Exchange server and send it back to the

'' SMTP Client.

If (DataMessage = True And SendingData = True) Or (DataMessage = False And SendingData = False) Then

If SendingData = True Then DataMessage = False

ReDim ArriveArray(2048)

infoRecieved = ExchangeSocket.Client.Receive(ArriveArray)

SMTPMessage = Encoding.ASCII.GetString(ArriveArray)

SendArray = Encoding.ASCII.GetBytes(Replace(SMTPMessage, Chr(0), "").ToCharArray())

currentSocket.Send(SendArray, SendArray.Length, 0)

End If

If LCase(SMTPMessage).StartsWith("quit") Or SMTPMessage.StartsWith("221") Then Exit While

End While

Catch ex As Exception

End Try

Try

ExchangeSocket.Close()

Catch ex As Exception

End Try

Try

myListener.EndAcceptSocket(currentSocket)

currentSocket.Close()

Catch ex As Exception

End Try

ExchangeSocket = Nothing

currentSocket = Nothing

EMailContent(contentString)

End Sub



Answer this question

Thread Problems – Strange Loop behavior

  • Jassim Rahma

    ner i made it in 2005, passing some things across threads is still safe, its things like setting the value of a text box in the primary thread from a new thread that is not safe.

    i think the lock is the way farward, thanks mate.


  • Thomas Frohberg

    Is this written in VS2003 or 2005

    I see this code:currentSocket = newSocket and it appears to be a cross thread call; which would mean this was written in VS03 'cause VS05 would throw an error when you ran this.

    If this was written in 03, and you've got cross thread calls, then there's no telling how screwy your results might get.



  • rayou

    I don't see any safeguards in your code...it may want be prudent to put locks on the primary data points within the critical sections such as



    Lock(1)
    myVar = 3
    Unlock(1)



    Check out Lock, Unlock Functions in the Visual Basic Language Reference. Here is another article that may be beneficial Concurency: What Ever Developer Must Know about MultiThreaded Applications.


  • Thread Problems – Strange Loop behavior