Solved

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

Posted on 2004-10-06
4
282 Views
Last Modified: 2008-02-01
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?
Regards.
I am open to split the points for any good design(s)
0
Comment
Question by:KarcOrigin
  • 2
4 Comments
 
LVL 9

Accepted Solution

by:
checoo earned 300 total points
ID: 12237969
To start with you need to use the TCPListen and TCPClient. Start the listening process on a seperate process, look at the samples below --

Server
=====

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)
        objThread.Start()
    End Sub

    Private Sub DoListen()
        Dim newClient As Client
        Try
            objListner = New TcpListener(IPAddress.Any, intListeningPort)
            objListner.Start()
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)
        Sender.DisposeClient()
        ClientCol.Remove(Sender.ClientID)
    End Sub

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

    Public Sub DisposeServer()
      'clean up code
    End Sub

End Class

Client
====

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
        Get
            Return myID.ToString
        End Get
    End Property

    Private Sub ReceiveClientData(ByVal asyncResult As IAsyncResult)
        Dim intcount As Integer
        Try
            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
            Else
                objText.Append(ChrW(Bytes(intIndex)))
            End If
        Next
    End Sub

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

    Public Sub Dispose()
     'Clean up code here
    End Sub
End Class
0
 
LVL 5

Author Comment

by:KarcOrigin
ID: 12245742
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.

Regards.
0
 
LVL 10

Assisted Solution

by:Hans Langer
Hans Langer earned 200 total points
ID: 12254389
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)
        objListener.Start()
        objThread = New Thread(AddressOf WaitClient)
        objThread.Start()
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

            Interlocked.Increment(lgnIdClient)

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

            sctClient.Thread.Start()
            End If
        End While
End Sub


public sub ReadDataClient()
Dim lngIdReal As Long = lgnIdClient
Dim sctClient As Client = CType(ClientList(lngIdReal), Client)
.....
end sub
0
 
LVL 5

Author Comment

by:KarcOrigin
ID: 12286580
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.
Regards.
0

Featured Post

What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

Article by: jpaulino
XML Literals are a great way to handle XML files and the community doesn’t use it as much as it should.  An XML Literal is like a String (http://msdn.microsoft.com/en-us/library/system.string.aspx) Literal, only instead of starting and ending with w…
If you need to start windows update installation remotely or as a scheduled task you will find this very helpful.
In this tutorial you'll learn about bandwidth monitoring with flows and packet sniffing with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're interested in additional methods for monitoring bandwidt…
This video shows how to remove a single email address from the Outlook 2010 Auto Suggestion memory. NOTE: For Outlook 2016 and 2013 perform the exact same steps. Open a new email: Click the New email button in Outlook. Start typing the address: …

747 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now