Design issue: How to handle multiple socket client with single socket server?

Dear Experts,
I have a socket server and multiple socket clients. How can my single socket server handle multiple socket clients simultaneously/concurrently? I am using MSWinSock control as server and client. I need to store number of socket client currently connected and their command requests and execute the commands and return the results to the requsted client command. What can be the good design to handle this issue?
I am open to split the points for any good design(s)
Who is Participating?
checooConnect With a Mentor Commented:
To start with you need to use the TCPListen and TCPClient. Start the listening process on a seperate process, look at the samples below --


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

Public Class SocketServer

    Private ClientCol As Hashtable
    Private objThread As Thread
    Private objListner As TcpListener
    Private intListeningPort As Integer

    Public Sub New(ByVal intPort As Integer)
        ClientCol = New Hashtable
        intListeningPort = intPort
        objThread = New Thread(AddressOf DoListen)
    End Sub

    Private Sub DoListen()
        Dim newClient As Client
            objListner = New TcpListener(IPAddress.Any, intListeningPort)
aaa:        Do
                newClient = New Client(objListner.AcceptTcpClient, strConnectionString)
                ClientCol.Add(newClient.ClientID, newClient)
                AddHandler newClient.Connected, AddressOf onConnected
                AddHandler newClient.Disconnected, AddressOf onDisconected
                AddHandler newClient.DataReceived, AddressOf onDataReceived
            Loop Until False
        Catch e As Exception
            GoTo aaa
        End Try
    End Sub

    Private Sub onConnected(ByVal Sender As Client)
        ClientCol.Add(Sender.ClientID, Sender)
    End Sub

    Private Sub onDisconected(ByVal Sender As Client)
    End Sub

    Private Sub onDataReceived(ByVal Sender As Client, ByVal strData As String)
            'write code to process the inputs
        Catch e As Exception
        End Try
    End Sub

    Public Sub DisposeServer()
      'clean up code
    End Sub

End Class


Imports System.Net.Sockets
Imports System.Text

Public Class Client
    Public Event Connected(ByVal sender As Client)
    Public Event Disconnected(ByVal sender As Client)
    Public Event DataReceived(ByVal sender As Client, ByVal strData As String)

    Private myID As Guid
    Private objClient As TcpClient
    Private bClientData(1024) As Byte
    Private objText As New StringBuilder

    Public Sub New(ByVal Client As TcpClient, ByVal strConn As String)
        Dim strResponse As String
        objClient = Client
        objClient.NoDelay = True
        myID = Guid.NewGuid
    End Sub

    Public ReadOnly Property ClientID() As String
            Return myID.ToString
        End Get
    End Property

    Private Sub ReceiveClientData(ByVal asyncResult As IAsyncResult)
        Dim intcount As Integer
            SyncLock objClient.GetStream
                intcount = objClient.GetStream.EndRead(asyncResult)
            End SyncLock

            If intcount < 1 Then
                RaiseEvent Disconnected(Me)
                Exit Sub
            End If

            ByteToString(bClientData, intcount)

            SyncLock objClient.GetStream
                objClient.GetStream.BeginRead(bClientData, 0, 1024, AddressOf ReceiveClientData, Nothing)
            End SyncLock

        Catch e As Exception
            RaiseEvent Disconnected(Me)
        End Try
    End Sub

    Private Sub ByteToString(ByVal Bytes() As Byte, ByVal intCount As Integer)
        Dim intIndex As Integer
        For intIndex = 0 To intCount - 1
            If Bytes(intIndex) = 94 Then
                RaiseEvent DataReceived(Me, objText.ToString)
                objText = New StringBuilder
            End If
    End Sub

    Public Sub Send(ByVal strData As String)
        SyncLock objClient.GetStream
            Dim wri As New IO.StreamWriter(objClient.GetStream)
        End SyncLock
    End Sub

    Public Sub Dispose()
     'Clean up code here
    End Sub
End Class
KarcOriginAuthor Commented:
Dear checoo and experts,

I do not have any control on the clients. Actually I am more interested of handling the client requests by the server only. Since MSWinSock can only handle one command at one time I need to implement the multiple simultaneously commands.

Consider the following case -
There are mulpitle clients connected to a socket server. For example clientA gives a command to scoket server and server return the result. This is fine. Now while processing the request of ClientA ClientB gave another command to the same server. Since the server and handle only one command at one time there must be some sort of Queue that has to be maintain or fulfill the requests in multitasking way. Can anyone suggest a good design to implement it?

Note: Just keep in mind that I cannot change the Socket Clients code what all I can do is with the Socket Server only. You can say that I want to make a multitasking or queue based Socket Server.

Hans LangerConnect With a Mentor Commented:
You can create a Thread for to listen Clients, anytime you hear one client create a child thread that only work with that client.
I hope this code can explain it better.

Private ClientList As New Hashtable
Private Shared lgnIdClient As Long = 0

Private Structure Client
        Public Socket As Socket
        Public Thread As Thread
        Public EndPoint As EndPoint
End Structure

Public Sub OpenConnection(ByVal IpAdress As String, ByVal Port As Integer)
        objListener = New TcpListener(System.Net.IPAddress.Parse(IpAdress), Port)
        objThread = New Thread(AddressOf WaitClient)
End Sub

Private Sub WaitClient()
        Dim sctClient As Client

        While true
             'Wait for a client
            sctClient.Socket = objListener.AcceptSocket()
            sctClient.EndPoint = sctClient.Socket.RemoteEndPoint ' objListener.LocalEndpoint


            sctCliente.Thread = New Thread(AddressOf ReadDataClient)
                SyncLock Me
                    ClientList.Add(lgnIdClient, sctClient)
                End SyncLock

            End If
        End While
End Sub

public sub ReadDataClient()
Dim lngIdReal As Long = lgnIdClient
Dim sctClient As Client = CType(ClientList(lngIdReal), Client)
end sub
KarcOriginAuthor Commented:
Dear checoo and GERENTE
Thank you very much for your comments. Applying your posted code I could'nt achive what I wanted to. Just to remind you guys that I wanted to process multiple clients request simultaneously...but your code gave me an idea and rest I used my own logic to achive my task.
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.