I've written a Windows-based TCP server program based on some VB code I found on the internet several years ago (I can't find the link now, but it was called "multi-client server program" or something like that).
The server communicates with a couple of Enterprise iPhone client apps that I have also developed. I've successfully incorporated this code into two separate server programs that work just fine on both the development server and the production server. I'm working on a third iOS client application and a corresponding server program, which works fine on the development machine, but will not work on the production server -- the same machine that hosts the other two server programs with no problem.
It was working for a while, but as I have added more functionality to the server class, it seems to have stopped processing the incoming data, but only on the production machine.
The code that performs the connection functions is contained in a separate public class which is supposed to communicate with the Windows form that processes the incoming data. Using msgbox's for debugging tools, I have been able to confirm that the Client Connection class is connecting and is receiving the data, but it for some reason will not communicate that data with the Windows form.
My only thought is that it must be a threading issue, but I am not sure, and I have no idea how to find out.
To recap, just to be clear:
- The code works fine on the development server, but not on the production server.
- The client connection class is identical in every way with the other two working server programs.
- That the client is communicating with the client connection class has been confirmed. The incoming data can be captured inside the connection class and displayed in msgbox's, so the data is getting through.
- The Windows class that processes the incoming data is not receiving the data from the public client connection class.
EDIT: I should have included this in the original post: The development server is Win 7; the production sever is Windows Server 2012.
Because of the complexity of this code, I am not sure what snippets would be applicable for this, but I'll do my best to include what makes most sense to me here.
This is the entirety of the client connection class with the exception of the method that sends outgoing data. Again, this was copied from a website several years ago, and the comments are those of the original developer:
Imports System.IO
Imports System.Net.Sockets
Imports System.Data.SqlClient
Public Class ConnectedClient
Private cli As TcpClient 'declare a tcp client which will be the client that we assign to an instance of this class
Private uniqueid As String 'this will be used for the name property
Dim strErrorLogPath As String
Public Property name ''This will be the name of the ID containing its Unique ID
Get
Return uniqueid 'when we want to get it, it will return the Unique ID
End Get
Set(ByVal value)
uniqueid = value 'Used for setting the name
End Set
End Property
Sub New(ByVal client As TcpClient)
Dim r As New Random 'create a new random to serve as way to create our unique ID
Dim x As String = String.Empty 'declare a new variable to hold the ID
For i = 0 To 7 'we are going to have an ID of 7 randomly generated characters
x &= Chr(r.Next(65, 89)) 'create a generate dnumber between 65 and 89 and get the letter that has the same ascii value (A-Z)
' and add it onto the ID string
Next
Me.name = client.Client.RemoteEndPoint.ToString().Remove(client.Client.RemoteEndPoint.ToString().LastIndexOf(":")) & " - " & x 'set the name to the Unique ID
cli = client 'assign the client specified to the TCP client variable to we can operate with it
cli.GetStream.BeginRead(New Byte() {0}, 0, 0, AddressOf read, Nothing) 'start reading using the read subroutine
End Sub
Public Event gotmessage(ByVal message As String, ByVal client As ConnectedClient) 'this is raised when we get a message from the client
Public Event disconnected(ByVal client As ConnectedClient) 'this is raised when the client disconnects
Sub read(ByVal ar As IAsyncResult) 'this will process all messages being received
'bn-note: This is the entry point of the data being received from the client.
Try
Dim sr As New StreamReader(cli.GetStream) 'initialize a new streamreader which will read from the client's stream
Dim msg As String = sr.ReadLine() 'create a new variable which will be used to hold the message being read
If msg = "" Then
RaiseEvent disconnected(Me) 'WE CAN ASSUME THE CLIENT HAS DISCONNECTED
Exit Try
'msg = "Null Message"
End If
WriteToRawIncomingDataLog(msg)
RaiseEvent gotmessage(msg, Me) 'tell the server a message has been received. Me is passed as an argument which represents
' the current client which it has received the message from to perform any client specific
' tasks if needed
cli.GetStream.BeginRead(New Byte() {0}, 0, 0, AddressOf read, Nothing) 'continue reading from the stream
'End Ifz
'Catch ex As System.NullReferenceException
Catch ex As Exception
Try 'if an error occurs in the reading purpose, we will try to read again to see if we still can read
Dim sr As New StreamReader(cli.GetStream) 'initialize a new streamreader which will read from the client's stream
Dim msg As String = sr.ReadLine() 'create a new variable which will be used to hold the message being read
WriteToRawIncomingDataLog(msg)
RaiseEvent gotmessage(msg, Me) 'tell the server a message has been received. Me is passed as an argument which represents
' the current client which it has received the message from to perform any client specific
' tasks if needed
cli.GetStream.BeginRead(New Byte() {0}, 0, 0, AddressOf read, Nothing) 'continue reading from the stream
'End If
'Catch ex2 As System.NullReferenceException
' Stop
Catch ' IF WE STILL CANNOT READ
RaiseEvent disconnected(Me) 'WE CAN ASSUME THE CLIENT HAS DISCONNECTED
End Try
End Try
End Sub
Here is the Windows form code that processes the incoming data:
Private Sub formMain_Load(sender As Object, e As System.EventArgs) Handles Me.Load
Try
Dim listener As New System.Threading.Thread(AddressOf listen) 'initialize a new thread for the listener so our GUI doesn't lag
listener.IsBackground = True
listener.Start(CInt(IncomingPortString)) 'start the listener, with the port specified as a parameter (textbox1 is our port textbox)
Catch ex As Exception
txtSystemMessages_AddText(String.Format("Error in formMain_Load sub: {0}{1}", ex.Message.ToString, vbNewLine))
End Try
End Sub
Sub listen(ByVal port As Integer)
Try
Dim t As New TcpListener(IPAddress.Any, port) 'declare a new tcplistener
t.Start() 'start the listener
Do
Dim client As New ConnectedClient(t.AcceptTcpClient) 'initialize a new connected client
AddHandler client.gotmessage, AddressOf received 'add the handler which will raise an event when a message is received
AddHandler client.disconnected, AddressOf disconnected 'add the handler which will raise an event when the client disconnects
Loop Until False
Catch ex As Exception
txtSystemMessages_AddText(String.Format("Error in Listen sub: {1}{2}", ex.Message.ToString, vbNewLine))
End Try
End Sub
Sub received(ByVal msg As String, ByVal client As ConnectedClient)
Try
If Not clients.ContainsKey(client) Then
clients.Add(client, client.name.ToString) 'add the client to our hashtable
End If
Catch ex As ArgumentException
End Try
(The sub that processes the incoming data string "msg".)
End Sub
I'm at a complete loss to know what could be causing this issue, and a threading issue is all that I can think of. Could a different machine have different threading schemes? Any help would be greatly appreciated.