Results 1 to 40 of 163

Thread: [RESOLVED] [2008] Can I add a TCPClient Component

Threaded View

  1. #11
    Raging swede Atheist's Avatar
    Join Date
    Aug 2005
    Location
    Sweden
    Posts
    8,018

    Re: [2008] Can I add a TCPClient Component

    Quote Originally Posted by perito
    i dont need it to be more effective. im still trying to make my client and server connect!!
    so the code u provide is only for the server not the client... ? right?
    im not understanding the code... is it for 2 programs or is it only for the server?

    if its only for the server, could you PLEASE show me how a client would connect..
    In the specific post by me that you linked too, there is only code for the server side. But in the same thread, I've got examples for the client side aswell.
    Anyway, I'll create one more example..

    Server side:
    Form:
    VB.Net Code:
    1. Public Class Form1
    2.     Private listener As System.Net.Sockets.TcpListener
    3.     Private listenThread As System.Threading.Thread
    4.  
    5.     Private clients As New List(Of ConnectedClient) 'This list will store all connected clients.
    6.  
    7.     Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    8.         listener = New System.Net.Sockets.TcpListener(System.Net.IPAddress.Any, 43001) 'The TcpListener will listen for incoming connections at port 43001
    9.         listener.Start() 'Start listening.
    10.         listenThread = New System.Threading.Thread(AddressOf doListen) 'This thread will run the doListen method
    11.         listenThread.IsBackground = True 'Since we dont want this thread to keep on running after the application closes, we set isBackground to true.
    12.         listenThread.Start() 'Start executing doListen on the worker thread.
    13.     End Sub
    14.  
    15.     Private Sub doListen()
    16.         Dim incomingClient As System.Net.Sockets.TcpClient
    17.         Do
    18.             incomingClient = listener.AcceptTcpClient 'Accept the incoming connection. This is a blocking method so execution will halt here until someone tries to connect.
    19.             Dim connClient As New ConnectedClient(incomingClient, Me) 'Create a new instance of ConnectedClient (check its constructor to see whats happening now).
    20.             AddHandler connClient.dataReceived, AddressOf Me.messageReceived
    21.             clients.Add(connClient) 'Adds the connected client to the list of connected clients.
    22.  
    23.         Loop
    24.     End Sub
    25.  
    26.     Public Sub removeClient(ByVal client As ConnectedClient)
    27.         If clients.Contains(client) Then
    28.             clients.Remove(client)
    29.         End If
    30.     End Sub
    31.  
    32.     Private Sub messageReceived(ByVal sender As ConnectedClient, ByVal message As String)
    33.         'A message has been received from one of the clients.
    34.         'To determine who its from, use the sender object.
    35.         'sender.SendMessage can be used to reply to the sender.
    36.  
    37.         Dim data() As String = message.Split("|"c) 'Split the message on each | and place in the string array.
    38.         Select Case data(0)
    39.             Case "CONNECT"
    40.                 'We use GetClientByName to make sure no one else is using this username.
    41.                 'It will return Nothing if the username is free.
    42.                 'Since the client sent the message in this format: CONNECT|UserName, the username will be in the array on index 1.
    43.                 If GetClientByName(data(1)) Is Nothing Then
    44.                     'The username is not taken, we can safely assign it to the sender.
    45.                     sender.Username = data(1)
    46.                 End If
    47.             Case "DISCONNECT"
    48.                 removeClient(sender)
    49.         End Select
    50.  
    51.     End Sub
    52.  
    53.     Private Function GetClientByName(ByVal name As String) As ConnectedClient
    54.         For Each cc As ConnectedClient In clients
    55.             If cc.Username = name Then
    56.                 Return cc 'client found, return it.
    57.             End If
    58.         Next
    59.         'If we've reached this part of the method, there is no client by that name
    60.         Return Nothing
    61.     End Function
    62. End Class
    ConnectedClient class:
    VB.Net Code:
    1. Public Class ConnectedClient
    2.     Private mClient As System.Net.Sockets.TcpClient
    3.  
    4.     Private mUsername As String
    5.     Private mParentForm As Form1
    6.     Private readThread As System.Threading.Thread
    7.     Private Const MESSAGE_DELIMITER As Char = ControlChars.Cr
    8.  
    9.     Public Event dataReceived(ByVal sender As ConnectedClient, ByVal message As String)
    10.  
    11.     Sub New(ByVal client As System.Net.Sockets.TcpClient, ByVal parentForm As Form1)
    12.         mParentForm = parentForm
    13.         mClient = client
    14.  
    15.         readThread = New System.Threading.Thread(AddressOf doRead)
    16.         readThread.IsBackground = True
    17.         readThread.Start()
    18.     End Sub
    19.  
    20.     Public Property Username() As String
    21.         Get
    22.             Return mUsername
    23.         End Get
    24.         Set(ByVal value As String)
    25.             mUsername = value
    26.         End Set
    27.     End Property
    28.  
    29.     Private Sub doRead()
    30.         Const BYTES_TO_READ As Integer = 255
    31.         Dim readBuffer(BYTES_TO_READ) As Byte
    32.         Dim bytesRead As Integer
    33.         Dim sBuilder As New System.Text.StringBuilder
    34.         Do
    35.             bytesRead = mClient.GetStream.Read(readBuffer, 0, BYTES_TO_READ)
    36.             If (bytesRead > 0) Then
    37.                 Dim message As String = System.Text.Encoding.UTF8.GetString(readBuffer, 0, bytesRead)
    38.                 If (message.IndexOf(MESSAGE_DELIMITER) > -1) Then
    39.  
    40.                     Dim subMessages() As String = message.Split(MESSAGE_DELIMITER)
    41.  
    42.                     'The first element in the subMessages string array must be the last part of the current message.
    43.                     'So we append it to the StringBuilder and raise the dataReceived event
    44.                     sBuilder.Append(subMessages(0))
    45.                     RaiseEvent dataReceived(Me, sBuilder.ToString)
    46.                     sBuilder = New System.Text.StringBuilder
    47.  
    48.                     'If there are only 2 elements in the array, we know that the second one is an incomplete message,
    49.                     'though if there are more then two then every element inbetween the first and the last are complete messages:
    50.                     If subMessages.Length = 2 Then
    51.                         sBuilder.Append(subMessages(1))
    52.                     Else
    53.                         For i As Integer = 1 To subMessages.GetUpperBound(0) - 1
    54.                             RaiseEvent dataReceived(Me, subMessages(i))
    55.                         Next
    56.                         sBuilder.Append(subMessages(subMessages.GetUpperBound(0)))
    57.                     End If
    58.                 Else
    59.  
    60.                     'MESSAGE_DELIMITER was not found in the message, so we just append everything to the stringbuilder.
    61.                     sBuilder.Append(message)
    62.                 End If
    63.             End If
    64.         Loop
    65.     End Sub
    66.  
    67.     Public Sub SendMessage(ByVal msg As String)
    68.         Dim sw As IO.StreamWriter
    69.         Try
    70.             SyncLock mClient.GetStream
    71.                 sw = New IO.StreamWriter(mClient.GetStream) 'Create a new streamwriter that will be writing directly to the networkstream.
    72.                 sw.Write(msg)
    73.                 sw.Flush()
    74.             End SyncLock
    75.         Catch ex As Exception
    76.             MessageBox.Show(ex.ToString)
    77.         End Try
    78.         'As opposed to writing to a file, we DONT call close on the streamwriter, since we dont want to close the stream.
    79.     End Sub
    80.  
    81. End Class

    Client Side:
    Form:
    VB.Net Code:
    1. Public Class Form1
    2.     Private client As System.Net.Sockets.TcpClient
    3.  
    4.     Private Const BYTES_TO_READ As Integer = 255
    5.     Private readBuffer(BYTES_TO_READ) As Byte
    6.  
    7.     Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    8.         client = New System.Net.Sockets.TcpClient("localhost", 43001)
    9.         client.GetStream.BeginRead(readBuffer, 0, BYTES_TO_READ, AddressOf doRead, Nothing)
    10.     End Sub
    11.  
    12.     Private Sub doRead(ByVal ar As System.IAsyncResult)
    13.         Dim totalRead As Integer
    14.         Try
    15.             totalRead = client.GetStream.EndRead(ar) 'Ends the reading and returns the number of bytes read.
    16.         Catch ex As Exception
    17.             'The underlying socket have probably been closed OR an error has occured whilst trying to access it, either way, this is where you should remove close all eventuall connections
    18.             'to this client and remove it from the list of connected clients.
    19.         End Try
    20.  
    21.             If totalRead > 0 Then
    22.                 'the readBuffer array will contain everything read from the client.
    23.                 Dim receivedString As String = System.Text.Encoding.UTF8.GetString(readBuffer, 0, totalRead)
    24.                 messageReceived(receivedString)
    25.             End If
    26.  
    27.             Try
    28.                 client.GetStream.BeginRead(readBuffer, 0, BYTES_TO_READ, AddressOf doRead, Nothing) 'Begin the reading again.
    29.             Catch ex As Exception
    30.                 'The underlying socket have probably been closed OR an error has occured whilst trying to access it, either way, this is where you should remove close all eventuall connections
    31.                 'to this client and remove it from the list of connected clients.
    32.             End Try
    33.     End Sub
    34.  
    35.     Private Sub messageReceived(ByVal message As String)
    36.         MessageBox.Show(message)
    37.     End Sub
    38.  
    39.  
    40.  
    41.     Private Sub SendMessage(ByVal msg As String)
    42.         Dim sw As IO.StreamWriter
    43.         Try
    44.             sw = New IO.StreamWriter(client.GetStream)
    45.             sw.Write(msg)
    46.             sw.Flush()
    47.         Catch ex As Exception
    48.             MessageBox.Show(ex.ToString)
    49.         End Try
    50.     End Sub
    51. End Class
    You need to add more exception handling and possibly some SyncLocks upon accessing the different Streams. There are also some important things that I've left out, such as removing a client from the list of connected client upon disconnection.
    I've tried to put some comments in the code but dont hesitate to look the different methods/classes up on MSDN.

    Edit: I intend to update this example some day soon.
    Last edited by Atheist; Apr 11th, 2009 at 07:23 AM.
    Rate posts that helped you. I do not reply to PM's with coding questions.
    How to Get Your Questions Answered
    Current project: tunaOS
    Me on.. BitBucket, Google Code, Github (pretty empty)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width