I have some code below that allows users to connect to a server's socket port and send messages to it. It relays information back to the client. I need the server app (code below) to relay the info to all clients. I think my problem is due to using an asychronous connection. Can anyone help me I am just trying to have all messages sent in relayed to all clients connected to the port.


Imports System.Net
Imports System.Net.Sockets
Imports System.Threading

Public Class Form1
Inherits System.Windows.Forms.Form

Private Listening As Boolean
Private ASCII As New System.Text.ASCIIEncoding()
Private Shared _count As Int32 = 0

#Region " Windows Form Designer generated code "

Public Sub New()

'This call is required by the Windows Form Designer.

'Add any initialization after the InitializeComponent() call

End Sub

'Form overrides dispose to clean up the component list.
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If Not (components Is Nothing) Then
End If
End If
End Sub

'Required by the Windows Form Designer
Private components As System.ComponentModel.IContainer

'NOTE: The following procedure is required by the Windows Form Designer
'It can be modified using the Windows Form Designer.
'Do not modify it using the code editor.
Friend WithEvents txtPort As System.Windows.Forms.TextBox
Friend WithEvents Label1 As System.Windows.Forms.Label
Friend WithEvents btnStart As System.Windows.Forms.Button
Friend WithEvents ListBox1 As System.Windows.Forms.ListBox
<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
Me.txtPort = New System.Windows.Forms.TextBox
Me.Label1 = New System.Windows.Forms.Label
Me.btnStart = New System.Windows.Forms.Button
Me.ListBox1 = New System.Windows.Forms.ListBox
Me.txtPort.Location = New System.Drawing.Point(72, 24)
Me.txtPort.Name = "txtPort"
Me.txtPort.Size = New System.Drawing.Size(100, 20)
Me.txtPort.TabIndex = 0
Me.txtPort.Text = "9980"
Me.Label1.Location = New System.Drawing.Point(16, 24)
Me.Label1.Name = "Label1"
Me.Label1.Size = New System.Drawing.Size(48, 23)
Me.Label1.TabIndex = 1
Me.Label1.Text = "Port No:"
Me.btnStart.Location = New System.Drawing.Point(600, 24)
Me.btnStart.Name = "btnStart"
Me.btnStart.Size = New System.Drawing.Size(75, 23)
Me.btnStart.TabIndex = 2
Me.btnStart.Text = "Start Server"
Me.ListBox1.Location = New System.Drawing.Point(16, 56)
Me.ListBox1.Name = "ListBox1"
Me.ListBox1.Size = New System.Drawing.Size(576, 173)
Me.ListBox1.TabIndex = 3
Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
Me.ClientSize = New System.Drawing.Size(704, 246)
Me.Name = "Form1"
Me.Text = "Form1"

End Sub

#End Region

Private Sub btnStart_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStart.Click
If Listening = False Then
Dim T As New Thread(AddressOf Listen)
T.IsBackground = True
Me.Text = "Listening"
btnStart.Text = "Stop Server"
Listening = False
Me.Text = "Not Listening"
btnStart.Text = "Start Server"
End If
End Sub

Private Sub Listen()
Dim Listener As New TcpListener(txtPort.Text.ToString)
Listening = True
Do Until Listening = False
Dim sb As New SocketAndBuffer()
sb.Socket = Listener.AcceptSocket()
sb.Socket.BeginReceive(sb.Buffer, 0, sb.Buffer.Length, SocketFlags.None, AddressOf ReceiveCallBack, sb)
End Sub

Private Sub ReceiveCallBack(ByVal ar As IAsyncResult)
Dim sb As SocketAndBuffer = CType(ar.AsyncState, SocketAndBuffer)
Dim numbytes As Int32 = sb.Socket.EndReceive(ar)
If numbytes > 0 Then
'-- Convert the buffer to a string
Dim Receive As String = ASCII.GetString(sb.Buffer, 0, numbytes)

_count += 1
' If _count = 1 Then
' Else

'End If

If Receive.StartsWith("QUIT") Then
'-- Close the socket
'-- Show the data
Dim dlg As New ShowReceiveDataDelegate(AddressOf ShowReceiveData)
Dim args() As Object = {Receive}
Me.Invoke(dlg, args)
'-- Echo the data


'-- Clear the buffer
Array.Clear(sb.Buffer, 0, sb.Buffer.Length)
'-- Receive again
sb.Socket.BeginReceive(sb.Buffer, 0, sb.Buffer.Length, SocketFlags.None, AddressOf ReceiveCallBack, sb)
End If
End If
End Sub

Private Delegate Sub ShowReceiveDataDelegate(ByVal Data As String)

Private Sub ShowReceiveData(ByVal Data As String)
ListBox1.TopIndex = ListBox1.Items.Count - 1
End Sub

End Class

Public Class SocketAndBuffer
Public Socket As System.Net.Sockets.Socket
Public Buffer(0) As Byte
End Class

Re: Visual Basic General sockets - messages to all connected clients

Bruno Yu - MSFT


According to your question on asychronous socket connection, I would like to provide you the following code sample on the issue and hope that can help you:

Imports System

Imports System.Net

Imports System.Net.Sockets

Imports System.Text

Imports System.Threading

Imports Microsoft.VisualBasic

' State object for reading client data asynchronously

Public Class StateObject

' Client socket.

Public workSocket As Socket = Nothing

' Size of receive buffer.

Public Const BufferSize As Integer = 1024

' Receive buffer.

Public buffer(BufferSize) As Byte

' Received data string.

Public sb As New StringBuilder

End Class 'StateObject

Public Class AsynchronousSocketListener

' Thread signal.

Public Shared allDone As New ManualResetEvent(False)

' This server waits for a connection and then uses asychronous operations to

' accept the connection, get data from the connected client,

' echo that data back to the connected client.

' It then disconnects from the client and waits for another client.

Public Shared Sub Main()

' Data buffer for incoming data.

Dim bytes() As Byte = New [Byte](1023) {}

' Establish the local endpoint for the socket.

Dim ipHostInfo As IPHostEntry = Dns.Resolve(Dns.GetHostName())

Dim ipAddress As IPAddress = ipHostInfo.AddressList(0)

Dim localEndPoint As New IPEndPoint(ipAddress, 11000)

' Create a TCP/IP socket.

Dim listener As New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)

' Bind the socket to the local endpoint and listen for incoming connections.



While True

' Set the event to nonsignaled state.


' Start an asynchronous socket to listen for connections.

Console.WriteLine("Waiting for a connection...")

listener.BeginAccept(New AsyncCallback(AddressOf AcceptCallback), listener)

' Wait until a connection is made and processed before continuing.


End While

End Sub 'Main

Public Shared Sub AcceptCallback(ByVal ar As IAsyncResult)

' Get the socket that handles the client request.

Dim listener As Socket = CType(ar.AsyncState, Socket)

' End the operation.

Dim handler As Socket = listener.EndAccept(ar)

' Create the state object for the async receive.

Dim state As New StateObject

state.workSocket = handler

handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, New AsyncCallback(AddressOf ReadCallback), state)

End Sub 'AcceptCallback

Re: Visual Basic General sockets - messages to all connected clients

Bruno Yu - MSFT

Public Shared Sub ReadCallback(ByVal ar As IAsyncResult)

Dim content As String = String.Empty

' Retrieve the state object and the handler socket

' from the asynchronous state object.

Dim state As StateObject = CType(ar.AsyncState, StateObject)

Dim handler As Socket = state.workSocket

' Read data from the client socket.

Dim bytesRead As Integer = handler.EndReceive(ar)

If bytesRead > 0 Then

' There might be more data, so store the data received so far., 0, bytesRead))

' Check for end-of-file tag. If it is not there, read

' more data.

content =

If content.IndexOf("<EOF>") > -1 Then

' All the data has been read from the

' client. Display it on the console.

Console.WriteLine("Read {0} bytes from socket. " + vbLf + " Data : {1}", content.Length, content)

' Echo the data back to the client.

Send(handler, content)


' Not all data received. Get more.

handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, New AsyncCallback(AddressOf ReadCallback), state)

End If

End If

End Sub 'ReadCallback

Private Shared Sub Send(ByVal handler As Socket, ByVal data As String)

' Convert the string data to byte data using ASCII encoding.

Dim byteData As Byte() = Encoding.ASCII.GetBytes(data)

' Begin sending the data to the remote device.

handler.BeginSend(byteData, 0, byteData.Length, 0, New AsyncCallback(AddressOf SendCallback), handler)

End Sub 'Send

Private Shared Sub SendCallback(ByVal ar As IAsyncResult)

' Retrieve the socket from the state object.

Dim handler As Socket = CType(ar.AsyncState, Socket)

' Complete sending the data to the remote device.

Dim bytesSent As Integer = handler.EndSend(ar)

Console.WriteLine("Sent {0} bytes to client.", bytesSent)



' Signal the main thread to continue.


End Sub 'SendCallback

End Class 'AsynchronousSocketListener

Re: Visual Basic General sockets - messages to all connected clients


I am trying to figure out how this is different frommy code. I cant seem to get this working either even on my localhost (as the code below returns my ipaddress rather than a or .

Dim localEndPoint As New IPEndPoint(ipAddress, 9980)

Any ideas And will this code send a message to all users connected to the port or just a single user (that was the intention of my original post) Thanks for your help!

Re: Visual Basic General sockets - messages to all connected clients


After a long trial and error process and searching through a million of dead message boards I found the solution. This class is written in C# but is plug and play. df=100&forumid=240456&select=2222911&msg=2222911