Solved

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

Posted on 2004-10-06
4
295 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Creating an analog clock UserControl seems fairly straight forward.  It is, after all, essentially just a circle with several lines in it!  Two common approaches for rendering an analog clock typically involve either manually calculating points with…
The ECB site provides FX rates for major currencies since its inception in 1999 in the form of an XML feed. The files have the following format (reducted for brevity) (CODE) There are three files available HERE (http://www.ecb.europa.eu/stats/exch…
Are you ready to implement Active Directory best practices without reading 300+ pages? You're in luck. In this webinar hosted by Skyport Systems, you gain insight into Microsoft's latest comprehensive guide, with tips on the best and easiest way…

733 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