Vantage92
Vantage92

Reputation: 3

VB.NET TCP Server/Client - Get IP of connected client

I'm trying to get the IP address of the connected client but I don't know what I doing wrong. Where I can find it? I think near Sub AcceptClient. I was trying to convert cClient to string, but it always results to True or False. I'm trying to get the argument ar from cClient, which gives me an empty result.
Client.Client.RemoteEndPoint doesn't work or I can't use it correctly.


Form1.vb from Server project

Imports System.IO, System.Net, System.Net.Sockets

Public Class Form1
    Dim Listener As TcpListener
    Dim Client As TcpClient
    Dim ClientList As New List(Of ChatClient)
    Dim sReader As StreamReader
    Dim cClient As ChatClient

    Sub xLoad() Handles Me.Load
        Listener = New TcpListener(IPAddress.Any, 3818)
        Timer1.Start()
        Listener.Start()
        xUpdate("Server Started", False)
        Listener.BeginAcceptTcpClient(New AsyncCallback(AddressOf AcceptClient), Listener)
    End Sub

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        ''Set view property
        ListView1.View = View.Details
        ListView1.GridLines = True
        ListView1.FullRowSelect = True

        'Add column header
        ListView1.Columns.Add("Adres IP", 120)
        ListView1.Columns.Add("Nazwa użytkownika", 120)
    End Sub

    Sub AcceptClient(ByVal ar As IAsyncResult)
        cClient = New ChatClient(Listener.EndAcceptTcpClient(ar))
        AddHandler(cClient.MessageRecieved), AddressOf MessageRecieved

        AddHandler(cClient.ClientExited), AddressOf ClientExited
        ClientList.Add(cClient)
        xUpdate("New Client Joined", True)

        Listener.BeginAcceptTcpClient(New AsyncCallback(AddressOf AcceptClient), Listener)
    End Sub

    Sub MessageRecieved(ByVal Str As String)
        xUpdate(Str, True)
    End Sub

    Sub ClientExited(ByVal Client As ChatClient)
        ClientList.Remove(Client)
        xUpdate("Client Exited", True)
    End Sub

    Delegate Sub _xUpdate(ByVal Str As String, ByVal Relay As Boolean)
    Sub xUpdate(ByVal Str As String, ByVal Relay As Boolean)
        On Error Resume Next
        If InvokeRequired Then
            Invoke(New _xUpdate(AddressOf xUpdate), Str, Relay)
        Else
            Dim nStart As Integer
            Dim nLast As Integer

            If Str.Contains("</>") Then
                nStart = InStr(Str, "</></>") + 7
                nLast = InStr(Str, "<\><\>")
                Str = Mid(Str, nStart, nLast - nStart)

                'dzielenie strina po odpowiednim syymbolu na przed i po symbolu :D

                Dim mystr As String = Str
                Dim cut_at As String = ","
                Dim x As Integer = InStr(mystr, cut_at)

                Dim string_before As String = mystr.Substring(0, x - 1)
                Dim string_after As String = mystr.Substring(x + cut_at.Length - 1)

                Dim otherItems As String() = {string_after}
                ListView1.Items.Add(string_before).SubItems.AddRange(otherItems) 'use SubItems
            ElseIf Str.Contains("<A>") Then
                nStart = InStr(Str, "<A>") + 4
                nLast = InStr(Str, "<B>")
                Str = Mid(Str, nStart, nLast - nStart)

                ListBox2.Items.Add(Str & vbNewLine)
            Else
                TextBox1.AppendText(Str & vbNewLine)
                If Relay Then Send(Str & vbNewLine)
            End If
        End If
    End Sub

    Private Sub TextBox2_KeyDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles TextBox2.KeyDown
        If e.KeyCode = Keys.Enter Then
            e.SuppressKeyPress = True
            xUpdate("Server Says: " & TextBox2.Text, True)
            TextBox2.Clear()
        End If
    End Sub

    Sub Send(ByVal Str As String)
        For i As Integer = 0 To ClientList.Count - 1
            Try
                ClientList(i).Send(Str)
            Catch
                ClientList.RemoveAt(i)
            End Try
        Next
    End Sub
End Class


ChatClient.vb from Server project

Imports System.Net.Sockets, System.IO

Public Class ChatClient
    Public Event MessageRecieved(ByVal Str As String)
    Public Event ClientExited(ByVal Client As ChatClient)
    Private sWriter As StreamWriter
    Public Client As TcpClient

    Sub New(ByVal xclient As TcpClient)
        Client = xclient
        client.GetStream.BeginRead(New Byte() {0}, 0, 0, AddressOf Read, Nothing)
    End Sub

    Private Sub Read()
        Try
            Dim sr As New StreamReader(Client.GetStream)
            Dim msg As String = sr.ReadLine()
            RaiseEvent MessageRecieved(msg)
            Client.GetStream.BeginRead(New Byte() {0}, 0, 0, New AsyncCallback(AddressOf Read), Nothing)
        Catch
            RaiseEvent ClientExited(Me)
        End Try
    End Sub

    Public Sub Send(ByVal Message As String)
        sWriter = New StreamWriter(Client.GetStream)
        sWriter.WriteLine(Message)
        sWriter.Flush()
    End Sub
End Class

Upvotes: 0

Views: 5101

Answers (1)

Visual Vincent
Visual Vincent

Reputation: 18310

You can get the IP address from the underlying socket by converting the Socket.RemoteEndPoint property into an IPEndPoint:

Dim Address As IPAddress = CType(cClient.Client.Client.RemoteEndPoint, IPEndPoint).Address

MessageBox.Show(Address.ToString()) 'Example.

Upvotes: 1

Related Questions