Link to home
Start Free TrialLog in
Avatar of mediasoftware
mediasoftware

asked on

TcpClient C# to VB.NET 2008 translation

I have searched over the internet, for a method to use TcpClient Class in VB.NET 2008 with server that has Ipv6 address.

On MSDN website at this page:
http://msdn.microsoft.com/en-us/library/aa329755(v=VS.71).aspx

Microsoft said about TcpClient Constructor (): 'This constructor works only with IPv4 address types.'

On short, it looked like was impossible to use TcpClient from VB.NET to connect to an Ipv6 address.

After more searches I found a Microsoft example that was modifying the TcpClient Class to achieve the connection goal for both Ipv4 and Ipv6 addresses.

The modified Microsoft TcpClient Class example is on those pages:

http://www.koders.com/csharp/fidFD032EB98799A811A1D79F41F0E6DBEEF8E75432.aspx

http://msdn.krugle.com/kse/entfiles/gdpe/codeplex.com/scmi_17301/fx/src/net/system/net/sockets/tcpclient.cs#1

but both example are written in C#. Would you please help me with a vb.net version of this code ?

Please note that all code converters I tried so far, did not produce a working VB.NET 2008 code.

Thank you in advance.
Avatar of Bob Learned
Bob Learned
Flag of United States of America image

That looks like a whole lotta code to convert to VB.NET, and I don't think that sounds too appealing.  It might be more useful to figure out where you are having problems converting...
Avatar of mediasoftware
mediasoftware

ASKER

I only have trouble with three functions: Logging.On , SR.GetString and ValidationHelper.ValidateTcpPort which the VB IDE doesn't seem to recognize them.

If those three functions are not important for the code, perhaps I could remove them from all over the code.

You are right TheLearnedOne, sorry for my omission, here is the VB.NET code translation.


Imports System.Security.Permissions
Imports System.Threading

'------------------------------------------------------------------------------
' <copyright file="TCPClient.cs" company="Microsoft">
'     
'      Copyright (c) 2006 Microsoft Corporation.  All rights reserved.
'     
'      The use and distribution terms for this software are contained in the file
'      named license.txt, which can be found in the root of this distribution.
'      By using this software in any fashion, you are agreeing to be bound by the
'      terms of this license.
'     
'      You must not remove this notice, or any other, from this software.
'     
' </copyright>
'------------------------------------------------------------------------------


Namespace System.Net.Sockets


	''' <devdoc>
	''' <para>The <see cref='System.Net.Sockets.TcpClient'/> class provide TCP services at a higher level
	'''    of abstraction than the <see cref='System.Net.Sockets.Socket'/> class. <see cref='System.Net.Sockets.TcpClient'/>
	'''    is used to create a Client connection to a remote host.</para>
	''' </devdoc>
	Public Class TcpClient
		Implements IDisposable

		Private m_ClientSocket As Socket
		Private m_Active As Boolean
		Private m_DataStream As NetworkStream

		'
		' IPv6: Maintain address family for the client
		'
		Private m_Family As AddressFamily = AddressFamily.InterNetwork

		' specify local IP and port
		''' <devdoc>
		'''    <para>
		'''       Initializes a new instance of the <see cref='System.Net.Sockets.TcpClient'/>
		'''       class with the specified end point.
		'''    </para>
		''' </devdoc>
		Public Sub New(ByVal localEP As IPEndPoint)
			If Logging.On Then
				Logging.Enter(Logging.Sockets, Me, "TcpClient", localEP)
			End If
			If localEP Is Nothing Then
				Throw New ArgumentNullException("localEP")
			End If
			'
			' IPv6: Establish address family before creating a socket
			'
			m_Family = localEP.AddressFamily

			initialize()
			Client.Bind(localEP)
			If Logging.On Then
				Logging.Exit(Logging.Sockets, Me, "TcpClient", "")
			End If
		End Sub

		' TcpClient(IPaddress localaddr); // port is arbitrary
		' TcpClient(int outgoingPort); // local IP is arbitrary

		' address+port is arbitrary
		''' <devdoc>
		'''    <para>
		'''       Initializes a new instance of the <see cref='System.Net.Sockets.TcpClient'/> class.
		'''    </para>
		''' </devdoc>
		Public Sub New()
			Me.New(AddressFamily.InterNetwork)
			If Logging.On Then
				Logging.Enter(Logging.Sockets, Me, "TcpClient", Nothing)
			End If
			If Logging.On Then
				Logging.Exit(Logging.Sockets, Me, "TcpClient", Nothing)
			End If
		End Sub

		''' <devdoc>
		'''    <para>
		'''       Initializes a new instance of the <see cref='System.Net.Sockets.TcpClient'/> class.
		'''    </para>
		''' </devdoc>
#If COMNET_DISABLEIPV6 Then
		Private Sub New(ByVal family As AddressFamily)
#Else
		Public Sub New(ByVal family As AddressFamily)
#End If
			If Logging.On Then
				Logging.Enter(Logging.Sockets, Me, "TcpClient", family)
			End If
			'
			' Validate parameter
			'
			If family <> AddressFamily.InterNetwork AndAlso family <> AddressFamily.InterNetworkV6 Then
				Throw New ArgumentException(SR.GetString(SR.net_protocol_invalid_family, "TCP"), "family")
			End If

			m_Family = family

			initialize()
			If Logging.On Then
				Logging.Exit(Logging.Sockets, Me, "TcpClient", Nothing)
			End If
		End Sub

		' bind and connect
		''' <devdoc>
		''' <para>Initializes a new instance of the <see cref='System.Net.Sockets.TcpClient'/> class and connects to the
		'''    specified port on the specified host.</para>
		''' </devdoc>
		Public Sub New(ByVal hostname As String, ByVal port As Integer)
			If Logging.On Then
				Logging.Enter(Logging.Sockets, Me, "TcpClient", hostname)
			End If
			If hostname Is Nothing Then
				Throw New ArgumentNullException("hostname")
			End If
			If Not ValidationHelper.ValidateTcpPort(port) Then
				Throw New ArgumentOutOfRangeException("port")
			End If
			'
			' IPv6: Delay creating the client socket until we have
			'       performed DNS resolution and know which address
			'       families we can use.
			'
			'initialize();

			Try
				Connect(hostname, port)

			Catch e As Exception
				If TypeOf e Is ThreadAbortException OrElse TypeOf e Is StackOverflowException OrElse TypeOf e Is OutOfMemoryException Then
					Throw
				End If

				If m_ClientSocket IsNot Nothing Then
					m_ClientSocket.Close()
				End If
				Throw e
			Catch
				If m_ClientSocket IsNot Nothing Then
					m_ClientSocket.Close()
				End If
				Throw
			End Try

			If Logging.On Then
				Logging.Exit(Logging.Sockets, Me, "TcpClient", Nothing)
			End If
		End Sub

		'
		' used by TcpListener.Accept()
		'
		Friend Sub New(ByVal acceptedSocket As Socket)
			If Logging.On Then
				Logging.Enter(Logging.Sockets, Me, "TcpClient", acceptedSocket)
			End If
			Client = acceptedSocket
			m_Active = True
			If Logging.On Then
				Logging.Exit(Logging.Sockets, Me, "TcpClient", Nothing)
			End If
		End Sub

		''' <devdoc>
		'''    <para>
		'''       Used by the class to provide
		'''       the underlying network socket.
		'''    </para>
		''' </devdoc>
		Public Property Client() As Socket
			Get
				Return m_ClientSocket
			End Get
			Set(ByVal value As Socket)
				m_ClientSocket = value
			End Set
		End Property

		''' <devdoc>
		'''    <para>
		'''       Used by the class to indicate that a connection has been made.
		'''    </para>
		''' </devdoc>
		Protected Property Active() As Boolean
			Get
				Return m_Active
			End Get
			Set(ByVal value As Boolean)
				m_Active = value
			End Set
		End Property

		Public ReadOnly Property Available() As Integer
			Get
				Return m_ClientSocket.Available
			End Get
		End Property
		Public ReadOnly Property Connected() As Boolean
			Get
				Return m_ClientSocket.Connected
			End Get
		End Property
		Public Property ExclusiveAddressUse() As Boolean
			Get
				Return m_ClientSocket.ExclusiveAddressUse
			End Get
			Set(ByVal value As Boolean)
				m_ClientSocket.ExclusiveAddressUse = value
			End Set
		End Property 'new



		''' <devdoc>
		'''    <para>
		'''       Connects the Client to the specified port on the specified host.
		'''    </para>
		''' </devdoc>
		Public Sub Connect(ByVal hostname As String, ByVal port As Integer)
			If Logging.On Then
				Logging.Enter(Logging.Sockets, Me, "Connect", hostname)
			End If
			If m_CleanedUp Then
				Throw New ObjectDisposedException(Me.GetType().FullName)
			End If
			If hostname Is Nothing Then
				Throw New ArgumentNullException("hostname")
			End If
			If Not ValidationHelper.ValidateTcpPort(port) Then
				Throw New ArgumentOutOfRangeException("port")
			End If
			'
			' Check for already connected and throw here. This check
			' is not required in the other connect methods as they
			' will throw from WinSock. Here, the situation is more
			' complex since we have to resolve a hostname so it's
			' easier to simply block the request up front.
			'
			If m_Active Then
				Throw New SocketException(SocketError.IsConnected)
			End If

			'
			' IPv6: We need to process each of the addresses return from
			'       DNS when trying to connect. Use of AddressList[0] is
			'       bad form.
			'


			Dim addresses() As IPAddress = Dns.GetHostAddresses(hostname)
			Dim lastex As Exception = Nothing
			Dim ipv6Socket As Socket = Nothing
			Dim ipv4Socket As Socket = Nothing

			Try
				If m_ClientSocket Is Nothing Then
					If Socket.OSSupportsIPv6 Then
						ipv6Socket = New Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp)
						ipv4Socket = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
					Else
						m_ClientSocket = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
					End If
				End If

				For Each address As IPAddress In addresses
					Try
						If m_ClientSocket Is Nothing Then
							'
							' We came via the <hostname,port> constructor. Set the
							' address family appropriately, create the socket and
							' try to connect.
							'
							If address.AddressFamily = AddressFamily.InterNetwork Then
								ipv4Socket.Connect(address,port)
								m_ClientSocket = ipv4Socket
								ipv6Socket.Close()
							Else
								ipv6Socket.Connect(address,port)
								m_ClientSocket = ipv6Socket
								ipv4Socket.Close()
							End If

							m_Family = address.AddressFamily
							m_Active = True
							Exit For
						ElseIf address.AddressFamily = m_Family Then
							'
							' Only use addresses with a matching family
							'
							Connect(New IPEndPoint(address,port))
							m_Active = True
							Exit For
						End If

					Catch ex As Exception
						If TypeOf ex Is ThreadAbortException OrElse TypeOf ex Is StackOverflowException OrElse TypeOf ex Is OutOfMemoryException Then
							Throw
						End If
						lastex = ex
					End Try
				Next address

			Catch ex As Exception
				If TypeOf ex Is ThreadAbortException OrElse TypeOf ex Is StackOverflowException OrElse TypeOf ex Is OutOfMemoryException Then
					Throw
				End If
				lastex = ex

			Finally

				'cleanup temp sockets if failed
				'main socket gets closed when tcpclient gets closed

				'did we connect?
				If Not m_Active Then
					If ipv6Socket IsNot Nothing Then
						ipv6Socket.Close()
					End If

					If ipv4Socket IsNot Nothing Then
						ipv4Socket.Close()
					End If


					'
					' The connect failed - rethrow the last error we had
					'
					If lastex IsNot Nothing Then
						Throw lastex
					Else
						Throw New SocketException(SocketError.NotConnected)
					End If
				End If
			End Try

			If Logging.On Then
				Logging.Exit(Logging.Sockets, Me, "Connect", Nothing)
			End If
		End Sub

		''' <devdoc>
		'''    <para>
		'''       Connects the Client to the specified port on the specified host.
		'''    </para>
		''' </devdoc>
		Public Sub Connect(ByVal address As IPAddress, ByVal port As Integer)
			If Logging.On Then
				Logging.Enter(Logging.Sockets, Me, "Connect", address)
			End If
			If m_CleanedUp Then
				Throw New ObjectDisposedException(Me.GetType().FullName)
			End If
			If address Is Nothing Then
				Throw New ArgumentNullException("address")
			End If
			If Not ValidationHelper.ValidateTcpPort(port) Then
				Throw New ArgumentOutOfRangeException("port")
			End If
			Dim remoteEP As New IPEndPoint(address, port)
			Connect(remoteEP)
			If Logging.On Then
				Logging.Exit(Logging.Sockets, Me, "Connect", Nothing)
			End If
		End Sub

		''' <devdoc>
		'''    <para>
		'''       Connect the Client to the specified end point.
		'''    </para>
		''' </devdoc>
		Public Sub Connect(ByVal remoteEP As IPEndPoint)
			If Logging.On Then
				Logging.Enter(Logging.Sockets, Me, "Connect", remoteEP)
			End If
			If m_CleanedUp Then
				Throw New ObjectDisposedException(Me.GetType().FullName)
			End If
			If remoteEP Is Nothing Then
				Throw New ArgumentNullException("remoteEP")
			End If
			Client.Connect(remoteEP)
			m_Active = True
			If Logging.On Then
				Logging.Exit(Logging.Sockets, Me, "Connect", Nothing)
			End If
		End Sub



		'methods
		Public Sub Connect(ByVal ipAddresses() As IPAddress, ByVal port As Integer)
			If Logging.On Then
				Logging.Enter(Logging.Sockets, Me, "Connect", ipAddresses)
			End If
			Client.Connect(ipAddresses, port)
			m_Active = True
			If Logging.On Then
				Logging.Exit(Logging.Sockets, Me, "Connect", Nothing)
			End If
		End Sub


		<HostProtection(ExternalThreading:=True)> _
		Public Function BeginConnect(ByVal host As String, ByVal port As Integer, ByVal requestCallback As AsyncCallback, ByVal state As Object) As IAsyncResult
			If Logging.On Then
				Logging.Enter(Logging.Sockets, Me, "BeginConnect", host)
			End If
			Dim result As IAsyncResult = Client.BeginConnect(host, port, requestCallback, state)
			If Logging.On Then
				Logging.Exit(Logging.Sockets, Me, "BeginConnect", Nothing)
			End If
			Return result
		End Function

		<HostProtection(ExternalThreading:=True)> _
		Public Function BeginConnect(ByVal address As IPAddress, ByVal port As Integer, ByVal requestCallback As AsyncCallback, ByVal state As Object) As IAsyncResult
			If Logging.On Then
				Logging.Enter(Logging.Sockets, Me, "BeginConnect", address)
			End If
			Dim result As IAsyncResult = Client.BeginConnect(address, port, requestCallback, state)
			If Logging.On Then
				Logging.Exit(Logging.Sockets, Me, "BeginConnect", Nothing)
			End If
			Return result
		End Function

		<HostProtection(ExternalThreading:=True)> _
		Public Function BeginConnect(ByVal addresses() As IPAddress, ByVal port As Integer, ByVal requestCallback As AsyncCallback, ByVal state As Object) As IAsyncResult

			If Logging.On Then
				Logging.Enter(Logging.Sockets, Me, "BeginConnect", addresses)
			End If
			Dim result As IAsyncResult = Client.BeginConnect(addresses, port, requestCallback, state)
			If Logging.On Then
				Logging.Exit(Logging.Sockets, Me, "BeginConnect", Nothing)
			End If
			Return result
		End Function

		Public Sub EndConnect(ByVal asyncResult As IAsyncResult)

			If Logging.On Then
				Logging.Enter(Logging.Sockets, Me, "EndConnect", asyncResult)
			End If
			Client.EndConnect(asyncResult)
			m_Active = True
			If Logging.On Then
				Logging.Exit(Logging.Sockets, Me, "EndConnect", Nothing)
			End If
		End Sub





		''' <devdoc>
		'''    <para>
		'''       Returns the stream used to read and write data to the
		'''       remote host.
		'''    </para>
		''' </devdoc>
		Public Function GetStream() As NetworkStream
			If Logging.On Then
				Logging.Enter(Logging.Sockets, Me, "GetStream", "")
			End If
			If m_CleanedUp Then
				Throw New ObjectDisposedException(Me.GetType().FullName)
			End If
			If Not Client.Connected Then
				Throw New InvalidOperationException(SR.GetString(SR.net_notconnected))
			End If
			If m_DataStream Is Nothing Then
				m_DataStream = New NetworkStream(Client, True)
			End If
			If Logging.On Then
				Logging.Exit(Logging.Sockets, Me, "GetStream", m_DataStream)
			End If
			Return m_DataStream
		End Function

		''' <devdoc>
		'''    <para>
		'''       Disposes the Tcp connection.
		'''    </para>
		''' </devdoc>
		'UEUE
		Public Sub Close()
			If Logging.On Then
				Logging.Enter(Logging.Sockets, Me, "Close", "")
			End If
			GlobalLog.Print("TcpClient::Close()")
			CType(Me, IDisposable).Dispose()
			If Logging.On Then
				Logging.Exit(Logging.Sockets, Me, "Close", "")
			End If
		End Sub

		Private m_CleanedUp As Boolean = False

		Protected Overridable Sub Dispose(ByVal disposing As Boolean)
			If Logging.On Then
				Logging.Enter(Logging.Sockets, Me, "Dispose", "")
			End If
			If m_CleanedUp Then
				If Logging.On Then
					Logging.Exit(Logging.Sockets, Me, "Dispose", "")
				End If
				Return
			End If

			If disposing Then
				Dim dataStream As IDisposable = m_DataStream
				If dataStream IsNot Nothing Then
					dataStream.Dispose()
				Else
					'
					' if the NetworkStream wasn't created, the Socket might
					' still be there and needs to be closed. In the case in which
					' we are bound to a local IPEndPoint this will remove the
					' binding and free up the IPEndPoint for later uses.
					'
					Dim chkClientSocket As Socket = Client
					If chkClientSocket IsNot Nothing Then
						Try
							chkClientSocket.InternalShutdown(SocketShutdown.Both)
						Finally
							chkClientSocket.Close()
							Client = Nothing
						End Try
					End If
				End If

				GC.SuppressFinalize(Me)
			End If

			m_CleanedUp = True
			If Logging.On Then
				Logging.Exit(Logging.Sockets, Me, "Dispose", "")
			End If
		End Sub

		''' <internalonly/>
		Private Sub Dispose() Implements IDisposable.Dispose
			Dispose(True)
		End Sub

		Protected Overrides Sub Finalize()
#If DEBUG Then
			GlobalLog.SetThreadSource(ThreadKinds.Finalization)
			Using GlobalLog.SetThreadKind(ThreadKinds.System Or ThreadKinds.Async)
#End If
			Dispose(False)
#If DEBUG Then
			End Using
#End If
		End Sub

		''' <devdoc>
		'''    <para>
		'''       Gets or sets the size of the receive buffer in bytes.
		'''    </para>
		''' </devdoc>
		Public Property ReceiveBufferSize() As Integer
			Get
				Return numericOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveBuffer)
			End Get
			Set(ByVal value As Integer)
				Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveBuffer, value)
			End Set
		End Property


		''' <devdoc>
		'''    <para>
		'''       Gets or
		'''       sets the size of the send buffer in bytes.
		'''    </para>
		''' </devdoc>
		Public Property SendBufferSize() As Integer
			Get
				Return numericOption(SocketOptionLevel.Socket, SocketOptionName.SendBuffer)
			End Get

			Set(ByVal value As Integer)
				Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendBuffer, value)
			End Set
		End Property

		''' <devdoc>
		'''    <para>
		'''       Gets or sets the receive time out value of the connection in seconds.
		'''    </para>
		''' </devdoc>
		Public Property ReceiveTimeout() As Integer
			Get
				Return numericOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout)
			End Get
			Set(ByVal value As Integer)
				Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, value)
			End Set
		End Property

		''' <devdoc>
		'''    <para>
		'''       Gets or sets the send time out value of the connection in seconds.
		'''    </para>
		''' </devdoc>
		Public Property SendTimeout() As Integer
			Get
				Return numericOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout)
			End Get

			Set(ByVal value As Integer)
				Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, value)
			End Set
		End Property

		''' <devdoc>
		'''    <para>
		'''       Gets or sets the value of the connection's linger option.
		'''    </para>
		''' </devdoc>
		Public Property LingerState() As LingerOption
			Get
				Return CType(Client.GetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Linger), LingerOption)
			End Get
			Set(ByVal value As LingerOption)
				Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Linger, value)
			End Set
		End Property

		''' <devdoc>
		'''    <para>
		'''       Enables or disables delay when send or receive buffers are full.
		'''    </para>
		''' </devdoc>
		Public Property NoDelay() As Boolean
			Get
				Return If(numericOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay) <> 0, True, False)
			End Get
			Set(ByVal value As Boolean)
				Client.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay,If(value, 1, 0))
			End Set
		End Property

		Private Sub initialize()
			'
			' IPv6: Use the address family from the constructor (or Connect method)
			'
			Client = New Socket(m_Family, SocketType.Stream, ProtocolType.Tcp)
			m_Active = False
		End Sub

		Private Function numericOption(ByVal optionLevel As SocketOptionLevel, ByVal optionName As SocketOptionName) As Integer
			Return CInt(Fix(Client.GetSocketOption(optionLevel, optionName)))
		End Function

	End Class ' class TCPClient


End Namespace ' namespace System.Net.Sockets

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of Bob Learned
Bob Learned
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thank you TheLearnedOne for your support and quick answers. I solved the Microsoft TcpClient Class example and the code works perfectly.

The single remaining question is regarding the equivalent of the C# LazyAsyncResult expression from the TcpListener class, but I will make another post for that.

Thank you again for your support.