Posted By

mcgraf on 03/24/09


Tagged

tcpsocketsclientserver


Versions (?)

Who likes this?

1 person have marked this snippet as a favorite

kengerb


TCP socket server example 2


 / Published in: VB.NET
 

  1. 'server side
  2. Public Class Form1
  3.  
  4. Private listener As System.Net.Sockets.TcpListener
  5.  
  6. Private listenThread As System.Threading.Thread
  7.  
  8.  
  9.  
  10. Private clients As New List(Of ConnectedClient) 'This list will store all connected clients.
  11.  
  12.  
  13.  
  14. Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
  15.  
  16. listener = New System.Net.Sockets.TcpListener(System.Net.IPAddress.Any, 43001) 'The TcpListener will listen for incoming connections at port 43001
  17.  
  18. listener.Start() 'Start listening.
  19.  
  20. listenThread = New System.Threading.Thread(AddressOf doListen) 'This thread will run the doListen method
  21.  
  22. listenThread.IsBackground = True 'Since we dont want this thread to keep on running after the application closes, we set isBackground to true.
  23.  
  24. listenThread.Start() 'Start executing doListen on the worker thread.
  25.  
  26. End Sub
  27.  
  28.  
  29.  
  30. Private Sub doListen()
  31.  
  32. Dim incomingClient As System.Net.Sockets.TcpClient
  33.  
  34. Do
  35.  
  36. incomingClient = listener.AcceptTcpClient 'Accept the incoming connection. This is a blocking method so execution will halt here until someone tries to connect.
  37.  
  38. Dim connClient As New ConnectedClient(incomingClient, Me) 'Create a new instance of ConnectedClient (check its constructor to see whats happening now).
  39.  
  40. AddHandler connClient.dataReceived, AddressOf Me.messageReceived
  41.  
  42. clients.Add(connClient) 'Adds the connected client to the list of connected clients.
  43.  
  44.  
  45.  
  46. Loop
  47.  
  48. End Sub
  49.  
  50.  
  51.  
  52. Public Sub removeClient(ByVal client As ConnectedClient)
  53.  
  54. If clients.Contains(client) Then
  55.  
  56. clients.Remove(client)
  57.  
  58. End If
  59.  
  60. End Sub
  61.  
  62.  
  63.  
  64. Private Sub messageReceived(ByVal sender As ConnectedClient, ByVal message As String)
  65.  
  66. 'A message has been received from one of the clients.
  67.  
  68. 'To determine who its from, use the sender object.
  69.  
  70. 'sender.SendMessage can be used to reply to the sender.
  71.  
  72.  
  73.  
  74. Dim data() As String = message.Split("|"c) 'Split the message on each | and place in the string array.
  75.  
  76. Select Case data(0)
  77.  
  78. Case "CONNECT"
  79.  
  80. 'We use GetClientByName to make sure no one else is using this username.
  81.  
  82. 'It will return Nothing if the username is free.
  83.  
  84. 'Since the client sent the message in this format: CONNECT|UserName, the username will be in the array on index 1.
  85.  
  86. If GetClientByName(data(1)) Is Nothing Then
  87.  
  88. 'The username is not taken, we can safely assign it to the sender.
  89.  
  90. sender.Username = data(1)
  91.  
  92. End If
  93.  
  94. Case "DISCONNECT"
  95.  
  96. removeClient(sender)
  97.  
  98. End Select
  99.  
  100.  
  101.  
  102. End Sub
  103.  
  104.  
  105.  
  106. Private Function GetClientByName(ByVal name As String) As ConnectedClient
  107.  
  108. For Each cc As ConnectedClient In clients
  109.  
  110. If cc.Username = name Then
  111.  
  112. Return cc 'client found, return it.
  113.  
  114. End If
  115.  
  116. Next
  117.  
  118. 'If we've reached this part of the method, there is no client by that name
  119.  
  120. Return Nothing
  121.  
  122. End Function
  123.  
  124. End Class
  125.  
  126. 'client side
  127.  
  128. Public Class ConnectedClient
  129.  
  130. Private mClient As System.Net.Sockets.TcpClient
  131.  
  132.  
  133.  
  134. Private mUsername As String
  135.  
  136. Private mParentForm As Form1
  137.  
  138. Private readThread As System.Threading.Thread
  139.  
  140. Private Const MESSAGE_DELIMITER As Char = ControlChars.Cr
  141.  
  142.  
  143.  
  144. Public Event dataReceived(ByVal sender As ConnectedClient, ByVal message As String)
  145.  
  146.  
  147.  
  148. Sub New(ByVal client As System.Net.Sockets.TcpClient, ByVal parentForm As Form1)
  149.  
  150. mParentForm = parentForm
  151.  
  152. mClient = client
  153.  
  154.  
  155.  
  156. readThread = New System.Threading.Thread(AddressOf doRead)
  157.  
  158. readThread.IsBackground = True
  159.  
  160. readThread.Start()
  161.  
  162. End Sub
  163.  
  164.  
  165.  
  166. Public Property Username() As String
  167.  
  168. Get
  169.  
  170. Return mUsername
  171.  
  172. End Get
  173.  
  174. Set(ByVal value As String)
  175.  
  176. mUsername = value
  177.  
  178. End Set
  179.  
  180. End Property
  181.  
  182.  
  183.  
  184. Private Sub doRead()
  185.  
  186. Const BYTES_TO_READ As Integer = 255
  187.  
  188. Dim readBuffer(BYTES_TO_READ) As Byte
  189.  
  190. Dim bytesRead As Integer
  191.  
  192. Dim sBuilder As New System.Text.StringBuilder
  193.  
  194. Do
  195.  
  196. bytesRead = mClient.GetStream.Read(readBuffer, 0, BYTES_TO_READ)
  197.  
  198. If (bytesRead > 0) Then
  199.  
  200. Dim message As String = System.Text.Encoding.UTF8.GetString(readBuffer, 0, bytesRead)
  201.  
  202. If (message.IndexOf(MESSAGE_DELIMITER) > -1) Then
  203.  
  204.  
  205.  
  206. Dim subMessages() As String = message.Split(MESSAGE_DELIMITER)
  207.  
  208.  
  209.  
  210. 'The first element in the subMessages string array must be the last part of the current message.
  211.  
  212. 'So we append it to the StringBuilder and raise the dataReceived event
  213.  
  214. sBuilder.Append(subMessages(0))
  215.  
  216. RaiseEvent dataReceived(Me, sBuilder.ToString)
  217.  
  218. sBuilder = New System.Text.StringBuilder
  219.  
  220.  
  221.  
  222. 'If there are only 2 elements in the array, we know that the second one is an incomplete message,
  223.  
  224. 'though if there are more then two then every element inbetween the first and the last are complete messages:
  225.  
  226. If subMessages.Length = 2 Then
  227.  
  228. sBuilder.Append(subMessages(1))
  229.  
  230. Else
  231.  
  232. For i As Integer = 1 To subMessages.GetUpperBound(0) - 1
  233.  
  234. RaiseEvent dataReceived(Me, subMessages(i))
  235.  
  236. Next
  237.  
  238. sBuilder.Append(subMessages(subMessages.GetUpperBound(0)))
  239.  
  240. End If
  241.  
  242. Else
  243.  
  244.  
  245.  
  246. 'MESSAGE_DELIMITER was not found in the message, so we just append everything to the stringbuilder.
  247.  
  248. sBuilder.Append(message)
  249.  
  250. End If
  251.  
  252. End If
  253.  
  254. Loop
  255.  
  256. End Sub
  257.  
  258.  
  259.  
  260. Public Sub SendMessage(ByVal msg As String)
  261.  
  262. Dim sw As IO.StreamWriter
  263.  
  264. Try
  265.  
  266. SyncLock mClient.GetStream
  267.  
  268. sw = New IO.StreamWriter(mClient.GetStream) 'Create a new streamwriter that will be writing directly to the networkstream.
  269.  
  270. sw.Write(msg)
  271.  
  272. sw.Flush()
  273.  
  274. End SyncLock
  275.  
  276. Catch ex As Exception
  277.  
  278. MessageBox.Show(ex.ToString)
  279.  
  280. End Try
  281.  
  282. 'As opposed to writing to a file, we DONT call close on the streamwriter, since we dont want to close the stream.
  283.  
  284. End Sub
  285.  
  286.  
  287.  
  288. End Class
  289.  
  290. 'client side form
  291.  
  292.  
  293. Public Class Form1
  294.  
  295. Private client As System.Net.Sockets.TcpClient
  296.  
  297.  
  298.  
  299. Private Const BYTES_TO_READ As Integer = 255
  300.  
  301. Private readBuffer(BYTES_TO_READ) As Byte
  302.  
  303.  
  304. Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
  305.  
  306. client = New System.Net.Sockets.TcpClient("localhost", 43001)
  307.  
  308. client.GetStream.BeginRead(readBuffer, 0, BYTES_TO_READ, AddressOf doRead, Nothing)
  309.  
  310. End Sub
  311.  
  312.  
  313.  
  314. Private Sub doRead(ByVal ar As System.IAsyncResult)
  315.  
  316. Dim totalRead As Integer
  317.  
  318. Try
  319.  
  320. totalRead = client.GetStream.EndRead(ar) 'Ends the reading and returns the number of bytes read.
  321.  
  322. Catch ex As Exception
  323.  
  324. '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
  325.  
  326. 'to this client and remove it from the list of connected clients.
  327.  
  328. End Try
  329.  
  330.  
  331.  
  332. If totalRead > 0 Then
  333.  
  334. 'the readBuffer array will contain everything read from the client.
  335.  
  336. Dim receivedString As String = System.Text.Encoding.UTF8.GetString(readBuffer, 0, totalRead)
  337.  
  338. messageReceived(receivedString)
  339.  
  340. End If
  341.  
  342.  
  343.  
  344. Try
  345.  
  346. client.GetStream.BeginRead(readBuffer, 0, BYTES_TO_READ, AddressOf doRead, Nothing) 'Begin the reading again.
  347.  
  348. Catch ex As Exception
  349.  
  350. '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
  351.  
  352. 'to this client and remove it from the list of connected clients.
  353.  
  354. End Try
  355.  
  356. End Sub
  357.  
  358.  
  359.  
  360. Private Sub messageReceived(ByVal message As String)
  361.  
  362. MessageBox.Show(message)
  363.  
  364. End Sub
  365.  
  366.  
  367.  
  368.  
  369.  
  370.  
  371.  
  372. Private Sub SendMessage(ByVal msg As String)
  373.  
  374. Dim sw As IO.StreamWriter
  375.  
  376. Try
  377.  
  378. sw = New IO.StreamWriter(client.GetStream)
  379.  
  380. sw.Write(msg)
  381.  
  382. sw.Flush()
  383.  
  384. Catch ex As Exception
  385.  
  386. MessageBox.Show(ex.ToString)
  387.  
  388. End Try
  389.  
  390. End Sub
  391.  
  392. End Class

Report this snippet  

Comments

RSS Icon Subscribe to comments
Posted By: dariofil on June 21, 2009

I got the connection happening. However; the client doesnt seem to send back messages? I can send messages from Server to Client no problems. But from Client to Server, it just does NOTHING. HELP!

Posted By: dariofil on June 21, 2009

Is it me,or the code - that is the first thing i need sorted out.

Posted By: dariofil on June 21, 2009

Lovely example - Multi Threaded Server - if only my client could talk back!

Posted By: dariofil on June 24, 2009

GOT IT TO WORK FINALLY.

I did have another issue of string passed doubleing. I send "test" i get "testtest".

I fixed it by sending "test|" as this splits the message transmitted into arrays.

You need to login to post a comment.