D
Dmitry Akselrod
Hello everyone,
I have a vb.net application that wraps the TCPListener object
in a class. The server connects to the local interface and establishes
itself on port 9900. It then polls for pending connections every 500ms.
I also have a vb6 application that uses the WinSock control at the other end
of the communication tunel. I have to work with vb6 here because it uses
less memory than .NET.
The WinSock control is not able to fully connect to the vb.net TCPListener.
The winsock.state is
constantly 6 (connecting). Thus I can never send a message to the .net
TCPlistener.
What's interesting is that:
a. I can do the reverse and connect to a vb6 WinSock control from vb.net
TCPClient and communicate without any issues.
b. According to debug information in .net the vb.net TCPListener
establishes a connection with the vb6 winsock control, but in vb6 world the
vb6 control thinks the status is "connecting"
Here is the .net Class that functions as the TCP server:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Imports System.Net.Sockets
Imports System.Text
Imports System.Net
Imports Microsoft.VisualBasic.Strings
Imports ControlChars = Microsoft.VisualBasic.ControlChars
Imports PrintMonitor.DataBaseConnection
Public Class SocketServer
' This class will control the WinSock server
' The server will answer client requests, such as request for a list of
project numbers
' default server binding is to the first ethernet interface and port
9900
Private ipAddress As ipAddress =
Dns.Resolve(Dns.GetHostName).AddressList(0)
Private Const PortNumber As Integer = 9900
' tcp server
Private TCPServer As TcpListener
Private IsListening As Boolean = False
Private PollTimer As New Timer()
' the client that initiates the connection
Private tcpClient As tcpClient
Private tcpSocket As Socket
' networkstream object
Private NetworkStream As NetworkStream
' Client Messages
Private Const ProjectListRequest As String = "REQUESTROJECT_LIST"
Private Const ExitRequest As String = "EXIT"
'repro database connection
Private db As New PrintMonitor.DataBaseConnection()
Public Sub New()
' initialize the server
Try
TCPServer = New TcpListener(ipAddress, PortNumber)
Catch e As System.Net.Sockets.SocketException
MessageBox.Show(e.Message)
End Try
'initialize timer
PollTimer.Interval = 500
PollTimer.Enabled = True
AddHandler PollTimer.tick, AddressOf PollTimer_Tick
End Sub
'overloaded
Public Sub New(ByVal ipAddress As ipAddress, ByVal PortNumber As
Integer)
' initialize the server
Try
TCPServer = New TcpListener(ipAddress, PortNumber)
Catch e As System.Net.Sockets.SocketException
MessageBox.Show(e.Message)
End Try
'initialize timer
PollTimer.Interval = 500
PollTimer.Enabled = True
AddHandler PollTimer.Tick, AddressOf PollTimer_Tick
End Sub
Public Sub startListening()
Try
TCPServer.Start()
Console.WriteLine("SERVER>listening on interface " &
ipAddress.ToString & _
" on port " & PortNumber.ToString & ".....")
IsListening = True
Catch e As System.Net.Sockets.SocketException
MessageBox.Show(e.Message)
End Try
' start the timer
PollTimer.Start()
End Sub
Public Sub stopListening()
If IsListening Then
TCPServer.Stop()
End If
IsListening = False
End Sub
Private Sub PollTimer_Tick(ByVal sender As Object, ByVal e As
System.EventArgs)
PollTimer.Start()
' if a conenction is pending, start a new thread and process
connection
If TCPServer.Pending Then
Dim tCheckForConnectionThread As System.Threading.Thread
tCheckForConnectionThread = New
System.Threading.Thread(AddressOf ProcessConnection)
tCheckForConnectionThread.IsBackground = True
tCheckForConnectionThread.Name = "Checking for Connection <" & _
System.DateTime.Now.ToString & ">"
tCheckForConnectionThread.Start()
'CheckForConnection()
End If
End Sub
Private Sub ProcessConnection()
If TCPServer.Pending Then
Try
tcpSocket = TCPServer.AcceptSocket
Console.WriteLine("SERVER>Connection accepted.")
' get and convert the message to a string for processing
Dim bReceivedBytes(1024) As Byte
If tcpSocket.Available > bReceivedBytes.Length Then
Console.WriteLine("ERROR: Received byte stream larger
than buffer. " & _
"Trancation has occured.")
End If
tcpSocket.Receive(bReceivedBytes)
Dim sStreamData As String =
Encoding.ASCII.GetString(bReceivedBytes)
AnalyzeClientMessage(sStreamData)
Catch e As System.Net.Sockets.SocketException
MessageBox.Show(e.Message.ToString)
End Try
End If
'clean up and kill the current thread
If Not IsNothing(tcpSocket) Then
If tcpSocket.Connected Then
Console.WriteLine("Closing Connection." )
tcpSocket.Close()
End If
End If
System.Threading.Thread.CurrentThread.Abort()
End Sub
Private Sub AnalyzeClientMessage(ByVal MessageText As String)
If InStr(MessageText, ProjectListRequest) Then
SendProjectList()
ElseIf InStr(MessageText, ExitRequest) Then
Console.WriteLine("SERVER>Exit command received. Closing
connection.")
Else
Console.WriteLine("SERVER>Message not understood.")
Console.WriteLine("SERVER>Received: " & MessageText &
ControlChars.CrLf)
End If
End Sub
Private Sub SendProjectList()
Console.WriteLine("SERVER>Project List was requested")
Dim sprojectlist As String = db.GetProjectList
sendMessage("RESPONSEROJECT_LIST:" & ControlChars.CrLf &
sprojectlist)
End Sub
Public Sub sendMessage(ByVal MessageText As String)
Try
If tcpSocket.Connected Then
Dim SendBytes(1024) As Byte
SendBytes = Encoding.ASCII.GetBytes(MessageText)
tcpSocket.Send(SendBytes, SendBytes.Length,
SocketFlags.None)
End If
Catch e As System.Net.Sockets.SocketException
MessageBox.Show(e.Message, "Connection Error", _
MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
Console.WriteLine("SERVER>: " & MessageText)
End Sub
End Class
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
An object from this class is initialized in a form for now, and the server
is immediately started.
The vb6 winsock control is initialized as in a menu function follows:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Private Sub mnuInformation_ProjListUpdate_Click()
'connect to server and retrieve project list
With frmPopUp.axWinsockClient
.RemoteHost = "192.168.1.49"
.RemotePort = CLng(9900)
Dim temp As Integer
temp = ServicePointManager.DefaultConnectionLimit
.Connect
Select Case axWinsockClient.State
Case 6
Debug.Print ("connecting....")
Case 7
Debug.Print ("connected to " & .RemoteHostIP & ":" &
..RemotePort)
End Select
If axWinsockClient.State = 7 Then .SendData ("REQUESTROJECT_LIST")
.Close
End With
End Sub
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Can anyone help me with this?
thanx,
Dmitry
I have a vb.net application that wraps the TCPListener object
in a class. The server connects to the local interface and establishes
itself on port 9900. It then polls for pending connections every 500ms.
I also have a vb6 application that uses the WinSock control at the other end
of the communication tunel. I have to work with vb6 here because it uses
less memory than .NET.
The WinSock control is not able to fully connect to the vb.net TCPListener.
The winsock.state is
constantly 6 (connecting). Thus I can never send a message to the .net
TCPlistener.
What's interesting is that:
a. I can do the reverse and connect to a vb6 WinSock control from vb.net
TCPClient and communicate without any issues.
b. According to debug information in .net the vb.net TCPListener
establishes a connection with the vb6 winsock control, but in vb6 world the
vb6 control thinks the status is "connecting"
Here is the .net Class that functions as the TCP server:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Imports System.Net.Sockets
Imports System.Text
Imports System.Net
Imports Microsoft.VisualBasic.Strings
Imports ControlChars = Microsoft.VisualBasic.ControlChars
Imports PrintMonitor.DataBaseConnection
Public Class SocketServer
' This class will control the WinSock server
' The server will answer client requests, such as request for a list of
project numbers
' default server binding is to the first ethernet interface and port
9900
Private ipAddress As ipAddress =
Dns.Resolve(Dns.GetHostName).AddressList(0)
Private Const PortNumber As Integer = 9900
' tcp server
Private TCPServer As TcpListener
Private IsListening As Boolean = False
Private PollTimer As New Timer()
' the client that initiates the connection
Private tcpClient As tcpClient
Private tcpSocket As Socket
' networkstream object
Private NetworkStream As NetworkStream
' Client Messages
Private Const ProjectListRequest As String = "REQUESTROJECT_LIST"
Private Const ExitRequest As String = "EXIT"
'repro database connection
Private db As New PrintMonitor.DataBaseConnection()
Public Sub New()
' initialize the server
Try
TCPServer = New TcpListener(ipAddress, PortNumber)
Catch e As System.Net.Sockets.SocketException
MessageBox.Show(e.Message)
End Try
'initialize timer
PollTimer.Interval = 500
PollTimer.Enabled = True
AddHandler PollTimer.tick, AddressOf PollTimer_Tick
End Sub
'overloaded
Public Sub New(ByVal ipAddress As ipAddress, ByVal PortNumber As
Integer)
' initialize the server
Try
TCPServer = New TcpListener(ipAddress, PortNumber)
Catch e As System.Net.Sockets.SocketException
MessageBox.Show(e.Message)
End Try
'initialize timer
PollTimer.Interval = 500
PollTimer.Enabled = True
AddHandler PollTimer.Tick, AddressOf PollTimer_Tick
End Sub
Public Sub startListening()
Try
TCPServer.Start()
Console.WriteLine("SERVER>listening on interface " &
ipAddress.ToString & _
" on port " & PortNumber.ToString & ".....")
IsListening = True
Catch e As System.Net.Sockets.SocketException
MessageBox.Show(e.Message)
End Try
' start the timer
PollTimer.Start()
End Sub
Public Sub stopListening()
If IsListening Then
TCPServer.Stop()
End If
IsListening = False
End Sub
Private Sub PollTimer_Tick(ByVal sender As Object, ByVal e As
System.EventArgs)
PollTimer.Start()
' if a conenction is pending, start a new thread and process
connection
If TCPServer.Pending Then
Dim tCheckForConnectionThread As System.Threading.Thread
tCheckForConnectionThread = New
System.Threading.Thread(AddressOf ProcessConnection)
tCheckForConnectionThread.IsBackground = True
tCheckForConnectionThread.Name = "Checking for Connection <" & _
System.DateTime.Now.ToString & ">"
tCheckForConnectionThread.Start()
'CheckForConnection()
End If
End Sub
Private Sub ProcessConnection()
If TCPServer.Pending Then
Try
tcpSocket = TCPServer.AcceptSocket
Console.WriteLine("SERVER>Connection accepted.")
' get and convert the message to a string for processing
Dim bReceivedBytes(1024) As Byte
If tcpSocket.Available > bReceivedBytes.Length Then
Console.WriteLine("ERROR: Received byte stream larger
than buffer. " & _
"Trancation has occured.")
End If
tcpSocket.Receive(bReceivedBytes)
Dim sStreamData As String =
Encoding.ASCII.GetString(bReceivedBytes)
AnalyzeClientMessage(sStreamData)
Catch e As System.Net.Sockets.SocketException
MessageBox.Show(e.Message.ToString)
End Try
End If
'clean up and kill the current thread
If Not IsNothing(tcpSocket) Then
If tcpSocket.Connected Then
Console.WriteLine("Closing Connection." )
tcpSocket.Close()
End If
End If
System.Threading.Thread.CurrentThread.Abort()
End Sub
Private Sub AnalyzeClientMessage(ByVal MessageText As String)
If InStr(MessageText, ProjectListRequest) Then
SendProjectList()
ElseIf InStr(MessageText, ExitRequest) Then
Console.WriteLine("SERVER>Exit command received. Closing
connection.")
Else
Console.WriteLine("SERVER>Message not understood.")
Console.WriteLine("SERVER>Received: " & MessageText &
ControlChars.CrLf)
End If
End Sub
Private Sub SendProjectList()
Console.WriteLine("SERVER>Project List was requested")
Dim sprojectlist As String = db.GetProjectList
sendMessage("RESPONSEROJECT_LIST:" & ControlChars.CrLf &
sprojectlist)
End Sub
Public Sub sendMessage(ByVal MessageText As String)
Try
If tcpSocket.Connected Then
Dim SendBytes(1024) As Byte
SendBytes = Encoding.ASCII.GetBytes(MessageText)
tcpSocket.Send(SendBytes, SendBytes.Length,
SocketFlags.None)
End If
Catch e As System.Net.Sockets.SocketException
MessageBox.Show(e.Message, "Connection Error", _
MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
Console.WriteLine("SERVER>: " & MessageText)
End Sub
End Class
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
An object from this class is initialized in a form for now, and the server
is immediately started.
The vb6 winsock control is initialized as in a menu function follows:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Private Sub mnuInformation_ProjListUpdate_Click()
'connect to server and retrieve project list
With frmPopUp.axWinsockClient
.RemoteHost = "192.168.1.49"
.RemotePort = CLng(9900)
Dim temp As Integer
temp = ServicePointManager.DefaultConnectionLimit
.Connect
Select Case axWinsockClient.State
Case 6
Debug.Print ("connecting....")
Case 7
Debug.Print ("connected to " & .RemoteHostIP & ":" &
..RemotePort)
End Select
If axWinsockClient.State = 7 Then .SendData ("REQUESTROJECT_LIST")
.Close
End With
End Sub
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Can anyone help me with this?
thanx,
Dmitry