Kip Posted June 22, 2008 Share Posted June 22, 2008 (edited) Hey,Because people always ask how to create a TCP client/server, and then (if they get it) don't know how to make it multi client,I simplified it. It's event driven, so you don't have to manualy check everything.Please read this whole post to understand my UDF.Version 3 of this UDF:Functions renamed, and everything is event-driven.Functions:_TCP_Server_Create($iPort, $sIP="0.0.0.0") _TCP_Server_Broadcast($sData) _TCP_Server_ClientList() _TCP_Server_ClientIP($hSocket) _TCP_Server_DisconnectClient($hSocket) _TCP_Server_Stop() _TCP_Client_Create($sIP , $iPort) _TCP_Client_Stop($hSocket) _TCP_Send($hSocket, $sText) _TCP_RegisterEvent($hSocket, $iEvent, $sFunction)Use _TCP_RegisterEvent() to register an event. These are the possible events to register:$TCP_SEND - When the other side of the connection is ready to receive (more) data.$TCP_RECEIVE - If something is received.$TCP_CONNECT - When you connect to the server. (Client only)$TCP_DISCONNECT - When a connection is closed.$TCP_NEWCLIENT - When a new client connects to the server. (Server only)Example client:#include "TCP.au3" ToolTip("CLIENT: Connecting...",10,10) $hClient = _TCP_Client_Create(@IPAddress1, 88); Create the client. Which will connect to the local ip address on port 88 _TCP_RegisterEvent($hClient, $TCP_RECEIVE, "Received"); Function "Received" will get called when something is received _TCP_RegisterEvent($hClient, $TCP_CONNECT, "Connected"); And func "Connected" will get called when the client is connected. _TCP_RegisterEvent($hClient, $TCP_DISCONNECT, "Disconnected"); And "Disconnected" will get called when the server disconnects us, or when the connection is lost. While 1 ; just to keep the program running WEnd Func Connected($hSocket, $iError); We registered this (you see?), When we're connected (or not) this function will be called. If not $iError Then; If there is no error... ToolTip("CLIENT: Connected!",10,10); ... we're connected. Else; ,else... ToolTip("CLIENT: Could not connect. Are you sure the server is running?",10,10); ... we aren't. EndIf EndFunc Func Received($hSocket, $sReceived, $iError); And we also registered this! Our homemade do-it-yourself function gets called when something is received. ToolTip("CLIENT: We received this: "& $sReceived, 10,10); (and we'll display it) EndFunc Func Disconnected($hSocket, $iError); Our disconnect function. Notice that all functions should have an $iError parameter. ToolTip("CLIENT: Connection closed or lost.", 10,10) EndFuncAnd the server: (which is smaller than the client)#include "TCP.au3" ToolTip("SERVER: Creating server...",10,30) $hServer = _TCP_Server_Create(88); A server. Tadaa! _TCP_RegisterEvent($hServer, $TCP_NEWCLIENT, "NewClient"); Whooooo! Now, this function (NewClient) get's called when a new client connects to the server. _TCP_RegisterEvent($hServer, $TCP_DISCONNECT, "Disconnect"); And this,... this will get called when a client disconnects. While 1 WEnd Func NewClient($hSocket, $iError); Yo, check this out! It's a $iError parameter! (In case you didn't noticed: It's in every function) ToolTip("SERVER: New client connected."&@CRLF&"Sending this: Bleh!",10,30) _TCP_Send($hSocket, "Bleh!"); Sending: "Bleh!" to the new client. (Yes, that's right: $hSocket is the socket of the new client.) EndFunc Func Disconnect($hSocket, $iError); Damn, we lost a client. Time of death: @Hour & @Min & @Sec :P ToolTip("SERVER: Client disconnected.",10,30); Placing a tooltip right under the tooltips of the client. EndFuncNow, as you can see, every function has an $iError parameter.Function($hSocket, $iError)Every funtion that is called can contain two parameters (1st: Socket, 2nd: Error) except for the Received function.Which should contain 3 parameters. 1:Socket, 2:Data, 3:ErrorYou can't create a server and a client in the same script.Well, I think that's all.Happy coding KipPrevious number of downloads: 975 TCP.au3 Edited May 25, 2010 by Kip SemEMP 1 MailSpons: Fake SMTP server for safe email testing Dutch postcode & address API. Link to comment Share on other sites More sharing options...
inet Posted June 26, 2008 Share Posted June 26, 2008 Hey, Because people always ask how to create a TCP client/server, and then (if they get it) don't know how to make it multi client, I simplified it. Client: (not very large, as you can see) #include "_TCP.au3" _TCP_Start(); Start all the tcp crap Do $iClientCreate = _TCP_Client_Create(@IPAddress1, 88); Connect to the server. I assume that the server is on the same computer. If not, change the ip address. Sleep(100) Until $iClientCreate <> -1; I put it in a loop so it doesn't matter if you start the server first or the client. Just put a nice Sleep() in it too. While 1 $sRecieved = _TCP_Client_Recieve($iClientCreate); Checks if we recieved something... If $sRecieved Then; If we actually recieved something, then... MsgBox(0,"Client","This is what we recieved:"&@CRLF&$sRecieved); ...we will show a messagebox. _TCP_Send($iClientCreate, "And this text is send from the client.") ExitLoop; Exit the loop, because we don't want to leave our connection here... all alone :) EndIf WEnd _TCP_Client_Stop($iClientCreate); Close our connection to the server. We've killed our connection. He's dead. He can't be alone anymore :P _TCP_Stop() ; Well, this isn't so hard... right? And the server: (also very small, and it support multiple clients) #include "_TCP.au3" _TCP_Start(); Start all the tcp crap, just like we did in the client. $iServerCreate = _TCP_Server_Create(88); Create the server on port 88. If you're a smart guy you can see that the client also connects to port 88. While 1 $iUpdate = _TCP_Server_Update($iServerCreate); Updates the server. Checks for new connections (clients), and puts them in an array. If $iUpdate Then; If a new client has connected. (That doesn't mean he also send something) MsgBox(0,"Server","Hey! We have a new client connected."); $iUpdate is the socket to the new client. If you don't get that, then just forget it. _TCP_Send($iUpdate, "This text is send from the server.") EndIf $sRecieved = _TCP_Server_Recieve(); Now we're gonna check if somebody send us something. ; btw: $sRecieved is an array. $sRecieved[0] contains the socket, and $sRecieved[1] contains the recieved text. If $sRecieved[0] Then; If a client has send something, then... MsgBox(0,"Server","I recieved something from a client!"&@CRLF&"Altough we're happy that it works I'm gonna close the client connection.") _TCP_Server_DisconnectClient($sRecieved[0]); Disconnect the client. ExitLoop; This example has nothing else to show, so i'm shutting down the server. EndIf WEnd _TCP_Server_Stop($iServerCreate) _TCP_Stop() ; Especially for a multi client server this is a very small script. I added nice comments, to let you understand better what is going on in the examples. Just remove the comments to make it more clear. If you have any questions, just ask. Hi Kip, Thanks for the enlighting script. I manage to setup a server and a client, they connect. But when i try to sent text to from the client to the server, the server detects there has been a transmission from the client, but $sReceived[1] does not contain anything. I put in a If IsArray($sReceived) right after If $sRecived[0] to check if the array is even initialised, but i get an error on that, so the array is not even excisting. What am i doing wrong? Link to comment Share on other sites More sharing options...
Kip Posted June 27, 2008 Author Share Posted June 27, 2008 The return value is ALWAYS an array. (as you can see:) Func _TCP_Server_Recieve($iBinary=0) Local $iReturn[2], $sRecv For $i = 1 to $_TCP_CLIENTS[0] If $_TCP_CLIENTS[$i] Then $sRecv = TCPRecv($_TCP_CLIENTS[$i], 1024, $iBinary) If $sRecv Then $iReturn[0] = $_TCP_CLIENTS[$i] $iReturn[1] = $sRecv Return $iReturn EndIf EndIf Next Return $iReturn EndFunc Does my example work? I put in a If IsArray($sReceived) right after If $sRecived[0]So you first check if an element of an array contains something, and then you're gonna check if it's an array at all? Could you post your code? MailSpons: Fake SMTP server for safe email testing Dutch postcode & address API. Link to comment Share on other sites More sharing options...
inet Posted June 27, 2008 Share Posted June 27, 2008 The return value is ALWAYS an array. (as you can see:) Func _TCP_Server_Recieve($iBinary=0) Local $iReturn[2], $sRecv For $i = 1 to $_TCP_CLIENTS[0] If $_TCP_CLIENTS[$i] Then $sRecv = TCPRecv($_TCP_CLIENTS[$i], 1024, $iBinary) If $sRecv Then $iReturn[0] = $_TCP_CLIENTS[$i] $iReturn[1] = $sRecv Return $iReturn EndIf EndIf Next Return $iReturn EndFunc Does my example work? So you first check if an element of an array contains something, and then you're gonna check if it's an array at all? Could you post your code? Yes i know i am checking double for the array, trange thing is that element[0] does containt the socket but element[1] does not excist. In you example you do check if there is received something, by checking element[0] but you never user element[1]. This is my receiving code $sRecieved = _TCP_Server_Recieve(); Now we're gonna check if somebody send us something. If $sRecieved[0] Then; If a client has send something, then... MsgBox(0, "", $sReceived[0]) $IPData = $sReceived[1] Select Case StringInStr($sReceived[1], "%clientping:") StringTrimLeft($IPData, 12) StringTrimRight($IPData, 1) _GUICtrlEdit_AppendText($ServerConsole, @CRLF & _GetTime(1) & " : New client handshaking from IP: " & $IPData) $ConClient[0] += 1 $ConClient[$ConClient[0]] = $IPData MsgBox(0, "", $ConClient[0]) _TCP_Send($sReceived[0], $Control[5]) _GUICtrlEdit_AppendText($ServerConsole, @CRLF & _GetTime(1) & " : Client succesfully logged in from IP: " & $IPData & "Sending login notification") _TCP_Send($sReceived[0], $Control[7]) Case StringInStr($sReceived[1], "%clientlogoff:") StringTrimLeft($IPData, 14) StringTrimRight($IPData, 1) _GUICtrlEdit_AppendText($ServerConsole, @CRLF & _GetTime(1) & " : Client succesfully logged out from IP: " & $IPData & "Sending logout notification") _TCP_Send($sReceived[0], $Control[8]) _TCP_Server_DisconnectClient($sRecieved[0]); Disconnect the client. EndSelect EndIf an you see what is going wrong? Link to comment Share on other sites More sharing options...
Kip Posted June 27, 2008 Author Share Posted June 27, 2008 1st: $sRecieved[1] should contain something (if something is send) 2nd: I don't see the logic behind this: StringTrimLeft($IPData, 12) StringTrimRight($IPData, 1)You never save the new string 3th: What if you put MsgBox(0, "", $sReceived[1]) right after MsgBox(0, "", $sReceived[0])? MailSpons: Fake SMTP server for safe email testing Dutch postcode & address API. Link to comment Share on other sites More sharing options...
inet Posted June 27, 2008 Share Posted June 27, 2008 (edited) 1st: $sRecieved[1] should contain something (if something is send) 2nd: I don't see the logic behind this: StringTrimLeft($IPData, 12) StringTrimRight($IPData, 1)You never save the new string 3th: What if you put MsgBox(0, "", $sReceived[1]) right after MsgBox(0, "", $sReceived[0])? This is my client code, at least the part where the handshaking is done. $Control[0] = "%clientping:"&@Ipaddress1&"%" Do $iClientCreate = _TCP_Client_Create(@IPAddress1, 33891); Connect to the server. I assume that the server is on the same computer. If not, change the ip address. If @error Then MsgBox(4112, "Error", "TCPConnect failed with WSA error: " & @error) Exit EndIf $i += 1 If $i >= 25 Then ExitLoop Sleep(100) Until $iClientCreate <> -1 If $iClientCreate = -1 Then _GUICtrlEdit_AppendText($ChatConsole, @CRLF & "Kabookie IM Server is not online, cannot connect to clients...") Else _TCP_Send($iClientCreate, $Control[0]) MsgBox(4112, "Error", "TCPConnect failed with WSA error: " & @error) _GUICtrlEdit_AppendText($ChatConsole, @CRLF & "Kabookie IM Server is online...") GUICtrlSetData($ServerStatus, "ServerStatus : Server is online and running... ") _GUICtrlEdit_AppendText($ChatConsole, @CRLF & "Sending handshake signal...") $Cycletimer1 = _GetTime(0) EndIf The StrinTrimLeft was indeed an error and is now fixed, thanks for pointing it out to me Edited June 27, 2008 by inet Link to comment Share on other sites More sharing options...
Kip Posted June 27, 2008 Author Share Posted June 27, 2008 (edited) I really wanna know this: 3th: What if you put MsgBox(0, "", $sReceived[1]) right after MsgBox(0, "", $sReceived[0])?(In the server) Edited June 27, 2008 by Kip MailSpons: Fake SMTP server for safe email testing Dutch postcode & address API. Link to comment Share on other sites More sharing options...
inet Posted June 27, 2008 Share Posted June 27, 2008 Hmmm this is strange, i did some more research and discovered that i get an array error on the line: If $sRecieved[0] Then What could this be? Link to comment Share on other sites More sharing options...
Kip Posted June 27, 2008 Author Share Posted June 27, 2008 I can't help you if you don't do this: 3th: What if you put MsgBox(0, "", $sReceived[1]) right after MsgBox(0, "", $sReceived[0])? What could this be?It would be helpful if you post the error too. MailSpons: Fake SMTP server for safe email testing Dutch postcode & address API. Link to comment Share on other sites More sharing options...
inet Posted June 27, 2008 Share Posted June 27, 2008 (edited) The messagebox is of no use i get the error before that on If $sRecieved[0] Then I get $sReceived possibly used before being declared. Edited June 27, 2008 by inet Link to comment Share on other sites More sharing options...
inet Posted June 27, 2008 Share Posted June 27, 2008 (edited) oohhhhh man, i got it. It was a stupid typo I typed If $sRecieved[0] then instead of If $sReceived[0] i switched ie for ei Been searching for hours, and now it's a plain old stupid typo.... It is working now Thanks for the help anyway Edited June 27, 2008 by inet Link to comment Share on other sites More sharing options...
Xandl Posted June 27, 2008 Share Posted June 27, 2008 Hello inet, there is a setting in autoit to avoid such a pain searching for a typo in the future. Simply put AutoItSetOption('MustDeclareVars',1) at the start of your scripts. Look up the detailed explanation in the help file, it will take care that every variable is declaired prior to use. I prefer to use this in my scripts, it might seem to be more work at start, but all in all, it really helps more then it costs. ciao Xandl Link to comment Share on other sites More sharing options...
DexterMorgan Posted June 27, 2008 Share Posted June 27, 2008 (edited) oohhhhh man, i got it. It was a stupid typo I typed If $sRecieved[0] then instead of If $sReceived[0] i switched ie for ei Been searching for hours, and now it's a plain old stupid typo.... It is working now Thanks for the help anyway Remember "I" before "e" except after "c" My teacher tells me that all the time ..... Yay i just realized school is over... lol Edited June 27, 2008 by Konstig code Link to comment Share on other sites More sharing options...
inet Posted June 27, 2008 Share Posted June 27, 2008 Remember "I" before "e" except after "c" My taecher tells me that all the time ..... Yay i just realized school is over... lolIt was not realy a typo, Kip used $sRecieved wich i copied and pasted into my script. But all the other times i used the variable i typed it as $sReceived so i was actualy using 2 variables for the same purpose. I just did not see that Kip spelled it the other way But it's fixed now.Thank you guys for all the tips and answers... Link to comment Share on other sites More sharing options...
Kip Posted June 27, 2008 Author Share Posted June 27, 2008 Remember "I" before "e" except after "c"I just did not see that Kip spelled it the other wayI never knew that either. MailSpons: Fake SMTP server for safe email testing Dutch postcode & address API. Link to comment Share on other sites More sharing options...
DexterMorgan Posted June 27, 2008 Share Posted June 27, 2008 I never knew that either. Lol code Link to comment Share on other sites More sharing options...
Skrip Posted June 27, 2008 Share Posted June 27, 2008 Very VERY nice kip. This can really help me. (Where is our Visual AutoIt? ) [left][sub]We're trapped in the belly of this horrible machine.[/sub][sup]And the machine is bleeding to death...[/sup][sup][/sup][/left] Link to comment Share on other sites More sharing options...
Kip Posted June 28, 2008 Author Share Posted June 28, 2008 New udf! It's now 10 times easier. (maybe even 11 times ) All old functions are still in the udf. New functions: _TcpEvent_Server_Create() _TcpEvent_Server_Send() _TcpEvent_Server_GetClientIP() _TcpEvent_Server_DisconnectClient() _TcpEvent_Server_Stop() _TcpEvent_Client_Create() _TcpEvent_Client_Send() _TcpEvent_Client_Stop() You don't have to know anything about sockets, etc. MailSpons: Fake SMTP server for safe email testing Dutch postcode & address API. Link to comment Share on other sites More sharing options...
DexterMorgan Posted June 28, 2008 Share Posted June 28, 2008 New udf! It's now 10 times easier. (maybe even 11 times )All old functions are still in the udf.New functions:_TcpEvent_Server_Create()_TcpEvent_Server_Send()_TcpEvent_Server_GetClientIP()_TcpEvent_Server_DisconnectClient()_TcpEvent_Server_Stop()_TcpEvent_Client_Create()_TcpEvent_Client_Send()_TcpEvent_Client_Stop()You don't have to know anything about sockets, etc.Nice I may need this.. Thanks code Link to comment Share on other sites More sharing options...
inet Posted June 28, 2008 Share Posted June 28, 2008 (edited) I already have my app running on the old UDF, but since you left all the old functions in it, i will upgrade to the new version Thanks Kip Edited June 28, 2008 by inet Link to comment Share on other sites More sharing options...
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