Click here to Skip to main content
15,892,298 members
Articles / Programming Languages / Visual Basic
Article

Get the client's IP address using TcpClient in VB.NET

Rate me:
Please Sign up or sign in to vote.
4.24/5 (31 votes)
4 May 2006CPOL3 min read 143.6K   49   6
How to get the client's IP address using TcpClient in VB.NET.

Introduction

This article demonstrates how to get the IP address for a remote client using the TcpClient object. There is already a nice solution for this in managed C++ here, but I needed to do this in VB.NET. Unfortunately, I could not get the cast that was used in the C++ solution to work in VB.NET. In addition, there is a much easier way that works in any .NET language!

Background

At TrayGames, we use the TcpListener object to establish a client-server communication for our multi-player online game platform. When a client connects to our server, we use the AcceptTcpClient method to accept the pending request which returns a TcpClient object to us. You could use the AcceptSocket method which gives you greater flexibility, returning a Socket object, but we wanted to use the TcpClient object.

Using the Code

The ClientConnection class encapsulates the TcpClient object. The full implementation of this class handles the sending and receiving of data across the TCP connection, but that's not the point of this article, so that code has been left out. The point of this article is the code that belongs in the PublicIPAddress property, which I'll show in minute. Only the basic members and methods are shown in the class below, though I've left the IDisposable implementation for completeness:

VB
Imports System.Net.Sockets 
Imports System.Reflection

Public NotInheritable Class ClientConnection 
Implements IDisposable       
   Private Client As TcpClient
   Private PublicIP As String

   ' TODO: Add code for PublicIPAddress property here

   Public Sub New(ByVal client As TcpClient)
        ' Validate parameters
        If client Is Nothing Then
           Throw New ArgumentNullException("client")
        End If
        Me.Client = client   
   End Sub

#Region " IDisposable Support "
   Private disposedValue  As Boolean ' To detect redundant calls
   Private Sub Dispose(ByVal disposing As Boolean)      
      If Not Me.disposedValue Then         
         If disposing Then            
               ' TODO: free unmanaged resources here
               If Not Client Is Nothing Then                  
                  Client.Close()                  
                  Client = Nothing               
               End If         
         End If         
         ' TODO: free shared unmanaged resources      
      End If
      Me.disposedValue = True   
   End Sub

   Public Sub Dispose() Implements IDisposable.Dispose      
      ' Do not change this code. Put cleanup code 
      ' in Dispose(ByVal disposing As Boolean) above.
      Dispose(True)      
      GC.SuppressFinalize(Me)
   End Sub
#End Region

End Class

One of the following properties, which demonstrate two different ways to get the remote IP address, is meant to be added to the ClientConnection class. The easiest way to get the IP address is to get the underlying Socket object through the Client method of the TcpClient object. Once you have the underlying socket, you can make a call to the RemoteEndPoint property which gets the EndPoint that contains the remote IP address and port number to which the Socket is connected. You must cast this EndPoint to an IPEndPoint before retrieving any information. You can then call the IPEndPoint.Address method to retrieve the remote IP address as shown below:

VB
Public ReadOnly Property PublicIPAddress() As String   
   Get      
      If PublicIP = String.Empty Then         
         Try            
            ' Get the clients IP address using Client property            
            Dim ipend As Net.IPEndPoint = Client.Client.RemoteEndPoint
            If Not ipend Is Nothing Then               
               PublicIP = ipend.Address.ToString            
            End If         
         Catch ex As System.ObjectDisposedException            
            PublicIP = String.Empty         
         Catch ex As SocketException            
            PublicIP = String.Empty        
         End Try       
      End If      
      Return PublicIP
   End Get
End Property

The other way to get the underlying Socket object is from a NetworkStream object. This object can be retrieved through the TcpClient object's GetStream method. Unfortunately, the Socket member is not accessible to us directly because it's marked Protected. You could derive your own class from NetworkStream, which is the solution used in the managed C++ article mentioned earlier, but the required cast doesn't seem to work in VB.NET. Instead, we can circumvent this protection by using a little reflection as shown below:

VB
Public ReadOnly Property PublicIPAddress() As String   
   Get      
      If PublicIP = String.Empty Then         
         Try            
            ' Get the clients IP address using reflection            
            Dim pi As PropertyInfo = _
               client.GetStream.GetType.GetProperty( _
               "Socket", BindingFlags.NonPublic Or BindingFlags.Instance)
             If Not pi Is Nothing Then               
                PublicIP = pi.GetValue(client.GetStream, _
                Nothing).RemoteEndPoint.ToString.Split(":")(0)
             End If        
         Catch ex As System.Exception            
             PublicIP = String.Empty        
         End Try      
     End If      
     Return PublicIP   
   End Get
End Property

Either version of the PublicIPAddress property will work fine. Note that you don't have to have a class that encapsulates the TcpClient object, you only need the TcpClient object itself for either of these techniques. That's all there is to it!

Points of Interest

This article is interesting if you want to learn some creative ways to manipulate the TcpClient object which provides client connections for TCP network services. Although this wasn't the most complicated topic, hopefully, I've saved someone a little time figuring this out! If you are interested in creating your own multi-player online games, you should check out the TGSDK which is downloadable from the TrayGames web site.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Founder SpreadTrends.com
United States United States
I've authored many articles that tackle real-world issues to save my peers in the development community valuable time. For example I've written articles that: show how to decode Ogg Vorbis audio files using the .NET Framework; describe best practices for Improving Entity Framework performance; and demonstrate step-by-step how to create a multi-player game.

Comments and Discussions

 
Generalgood work! Pin
Mubi | www.mrmubi.com19-May-11 4:09
professionalMubi | www.mrmubi.com19-May-11 4:09 
GeneralMy vote of 2 Pin
Edward DeGagne22-Mar-11 4:55
Edward DeGagne22-Mar-11 4:55 
GeneralMy vote of 5 Pin
jzx7512-Mar-11 13:06
jzx7512-Mar-11 13:06 
Questionabout get data to SQL ce from SQL server 2000 Pin
Chochiev Soslan19-Jul-07 3:12
Chochiev Soslan19-Jul-07 3:12 
GeneralPropertyinfo Problem Pin
mikeef3-May-06 20:51
mikeef3-May-06 20:51 
GeneralRe: Propertyinfo Problem Pin
Perry Marchant4-May-06 2:59
Perry Marchant4-May-06 2:59 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.