MobileMe15 Posted April 15, 2014 Posted April 15, 2014 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. expandcollapse popupTCPStartup() 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
FireFox Posted April 15, 2014 Posted April 15, 2014 (edited) 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 April 15, 2014 by FireFox
MobileMe15 Posted April 15, 2014 Author Posted April 15, 2014 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?
FireFox Posted April 15, 2014 Posted April 15, 2014 It's more complicated than that, but I'm not in the mood to edit a dirty code like that (no offence).
MobileMe15 Posted April 15, 2014 Author Posted April 15, 2014 It's more complicated than that, but I'm not in the mood to edit a dirty code like that (no offence). I know it's not pretty. I was just looking for a little guidance.
FireFox Posted April 15, 2014 Posted April 15, 2014 I will take a look at it later without any guarantee.
MobileMe15 Posted April 15, 2014 Author Posted April 15, 2014 I will take a look at it later without any guarantee. Thank you.
garbb Posted April 16, 2014 Posted April 16, 2014 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.
FireFox Posted April 16, 2014 Posted April 16, 2014 (edited) I haven't tested it, but it should work :expandcollapse popup#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 April 16, 2014 by FireFox
MobileMe15 Posted April 16, 2014 Author Posted April 16, 2014 Thanks again for the help. In order to get the data to duplicate to each client, would I have to put the data into an array also?
FireFox Posted April 16, 2014 Posted April 16, 2014 (edited) Do you want to echo to each client what each client sends to the server? Edited April 16, 2014 by FireFox
MobileMe15 Posted April 16, 2014 Author Posted April 16, 2014 Do you want to echo to each client what each client sends to the server? More or less. The server is getting the serial data from the MSS100, then distributing it to each of the clients that are connected.
FireFox Posted April 16, 2014 Posted April 16, 2014 expandcollapse popup#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()
MobileMe15 Posted April 16, 2014 Author Posted April 16, 2014 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?
FireFox Posted April 16, 2014 Posted April 16, 2014 The error may be : ;replace For $i = 0 To $iClientCount ;to For $i = 0 To $iClientCount -1
MobileMe15 Posted April 16, 2014 Author Posted April 16, 2014 (edited) Awesome! Thank you. Edited April 16, 2014 by MobileMe15
MobileMe15 Posted April 16, 2014 Author Posted April 16, 2014 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.
FireFox Posted April 17, 2014 Posted April 17, 2014 That's weird, it means the client which disconnects is always the last one connected.Yes you can remove it.
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now