Jump to content

Distributive TCP Server


Recommended Posts

I have an MSS100 serial to ip box that streams serial data in real-time.  I'm trying to create a tcp server where clients can telnet in and view the serial data.  I found some code and adapted it to my senario.  The server works, but I can only have one client connect at a time. 

The goal is to get multiple clients to connect to the server and view the same serial data at the same time.  Here is the code so far.  Any help would be great.  Thanks.

TCPStartup()

Global $Listen = TCPListen("0.0.0.0", 10001) ;Listen on all addresses on port 10001
If @error Then ;Uh-oh!
    ConsoleWrite("Error! Couldn't listen for clients on port 10001! Is another instance of this example already running?" & @CRLF)
    Exit 1 ;Exit with error-code 1
EndIf

Global $get = tcpconnect("192.168.0.73", "2001")
If @error Then
    ConsoleWrite("Error! Couldn't connect to MSS100!!!" & @CRLF)
    Exit 1
EndIf

While 1
    Global $iSock = TCPAccept($Listen) ;Check for new connections
    If $iSock = -1 Then ContinueLoop ;If no new connections are present, go back to the top of the loop and check again
    ConsoleWrite("A new client has connected!" & @CRLF) ;A wild connection appears!
    Local $sBuffer = "" ;Create a local receive buffer variable ---------------Working-------------
    ;ConsoleWrite("buffer cleared" & @CRLF)
    Local $bstring = ""
    While 1 ;Go in to a loop to read everything the client sends in to the buffer
        Local $sRecv = TCPRecv($get, 1024, 1) ;Write up to 512 characters at a time in to the buffer
        If @error Then ;If the client disconnected, stop right here and check for new clients again
            ;ConsoleWrite("Client has disconnected. Now waiting for more clients..." & @CRLF)
            ExitLoop
        EndIf
        If $sRecv = "" Then ContinueLoop ;Client sent no data, go check again...
        $sBuffer = $sRecv ;Client did send data, throw this new data in to the buffer
        $bstring = BinaryToString($sBuffer, 1)
        ConsoleWrite($bstring); & @CRLF)
        If $bstring > "" Then ;If the client has sent an @CRLF (an enter button press), then do this

            TCPSend($iSock, $bstring); & @CRLF) ;Send their message they sent back to them
            If @error Then
            ConsoleWrite("Client Disconnected" & @CRLF)
            $sBuffer = "" ;Empty the temporary buffer and start waiting for more data
            $bstring = ""

            ExitLoop
        EndIf
            $sBuffer = "" ;Working
            $bstring = ""

        EndIf
    WEnd
    ;ContinueLoop
WEnd
Link to comment
Share on other sites

Hi,

Welcome to the autoit forum :)

You need to use arrays, each item of the array corresponds to a client.

;e.g
Local $aClients[10][2]

;can contain 10 clients
;sub data:
;  0: client socket
;  1: some other data

_

Br, FireFox.

Edited by FireFox
Link to comment
Share on other sites

Hi,

Welcome to the autoit forum :)

You need to use arrays, each item of the array corresponds to a client.

;e.g
Local $aClients[10][2]

;can contain 10 clients
;sub data:
;  0: client socket
;  1: some other data

_

Br, FireFox.

 

I'm new to autoit and programming.  I read http://www.autoitscript.com/wiki/Arrays and I'm having a hard time getting there.  In my example, would I make $iSock an array?

Link to comment
Share on other sites

Take a look at the "basic server" here: '?do=embed' frameborder='0' data-embedContent>>

Basically you need to get any new sockets from TCPaccept() and put them into an array and then make a loop that checks all those sockets for new data with TCPRecv().

This is for dealing with clients connecting to your server.

The connection that you need to make with your box or whatever at 192.168.0.73 will be a seperate connection and you won't need an array for that because there should only be one connection.

Link to comment
Share on other sites

I haven't tested it, but it should work :

#include <Array.au3>

TCPStartup()

;Listen on all addresses on port 10001
Local $iListenSocket = TCPListen("0.0.0.0", 10001)
If @error Then
    ConsoleWrite("Error! Couldn't listen for clients on port 10001! Is another instance of this example already running?" & @CRLF)
    Exit 1
EndIf

#cs
Local $iConnSocket = TCPConnect("192.168.0.73", 2001)
If @error Then
    ConsoleWrite("Error! Couldn't connect to MSS100!!!" & @CRLF)
    Exit 1
EndIf
#ce

;$aClients will contain client sockets
;here there can only be one client (array size = 1) but it will be ReDim[entioned]
Local $aClients[1], $iClientCount = 0

Local $iAccSocket = 0, $bRecv = "", $sRecv = ""

While 1
    ;check for new connections
    $iAccSocket = TCPAccept($iListenSocket)

    ;if there is a new connection
    If $iAccSocket <> - 1 Then
        ;add the client data (here the socket)
        $aClients[$iClientCount] = $iAccSocket

        ;increment the client count
        $iClientCount += 1

        ;redim the client array to add a new client later
        ReDim $aClients[$iClientCount + 1]
    EndIf

    ;loop to process each client
    For $i = 0 To $iClientCount
        ;recv up to 1024 bytes
        $bRecv = TCPRecv($aClients[$i], 1024, 1)

        ;if there is an error
        If @error And @error <> -1 Then
            ;disconnect client, delete its data
            _ArrayDelete($aClients, $i)

            ;decrement the client count
            $iClientCount -= 1
        EndIf

        ;if there is no data received, go to next client
        If BinaryLen($bRecv) = 0 Then ContinueLoop

        ;convert binary data received to string
        $sRecv = BinaryToString($bRecv)

        ;echo the data to client
        TCPSend($aClients[$i], $sRecv)
    Next
WEnd
Edited by FireFox
Link to comment
Share on other sites

#include <Array.au3>

TCPStartup()

;Listen on all addresses on port 10001
Local $iListenSocket = TCPListen("0.0.0.0", 10001)
If @error Then
    ConsoleWrite("Error! Couldn't listen for clients on port 10001! Is another instance of this example already running?" & @CRLF)
    Exit 1
EndIf

Local $iConnSocket = TCPConnect("192.168.0.73", 2001)
If @error Then
    ConsoleWrite("Error! Couldn't connect to MSS100!!!" & @CRLF)
    Exit 1
EndIf

;$aClients will contain client sockets
;here there can only be one client (array size = 1) but it will be ReDim[entioned]
Local $aClients[1], $iClientCount = 0

Local $iAccSocket = 0, $bRecv = ""

While 1
    ;check for new connections
    $iAccSocket = TCPAccept($iListenSocket)

    ;if there is a new connection
    If $iAccSocket <> -1 Then
        ;add the client data (here the socket)
        $aClients[$iClientCount] = $iAccSocket

        ;increment the client count
        $iClientCount += 1

        ;redim the client array to add a new client later
        ReDim $aClients[$iClientCount + 1]
    EndIf

    ;recv up to 1024 bytes
    $bRecv = TCPRecv($iConnSocket, 1024, 1)

    ;if there is an error
    If @error And @error <> -1 Then
        ExitLoop
    EndIf

    ;if there is no data received
    If BinaryLen($bRecv) = 0 Then ContinueLoop

    ;loop to process each client
    For $i = 0 To $iClientCount
        ;send the data to each client
        TCPSend($aClients[$i], $bRecv)

        ;if there is an error
        If @error Then
            ;disconnect client, delete its data
            TCPCloseSocket($aClients[$i])

            _ArrayDelete($aClients, $i)

            ;decrement the client count
            $iClientCount -= 1
        EndIf
    Next
WEnd

;terminate the script if the connection to the server is lost

TCPCloseSocket($iConnSocket)

;disconnect all clients
For $i = 0 To $iClientCount
    TCPCloseSocket($aClients[$i])
Next

TCPCloseSocket($iListenSocket)

TCPShutdown()

Link to comment
Share on other sites

What does this mean?

C:Documents and SettingsuserDesktopTCP Server.au3 (31) : ==> Subscript used with non-Array variable.:
$aClients[$iClientCount] = $iAccSocket
$aClients^ ERROR

The only referense I could find was this error was caused by a file or folder not being present.  Should $iClientCount be a variable?

Link to comment
Share on other sites

If I remove this part

If @error Then
;disconnect client, delete its data
TCPCloseSocket($aClients[$i])

            ConsoleWrite("Client disconnected" & @CRLF)

_ArrayDelete($aClients, $i)

;decrement the client count
$iClientCount -= 1
EndIf

would there be any negative effects?  I ask because if there are 4 clients and one disconnects, it will disconnect the last one that was connected.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...