Ranmaru Posted November 16, 2007 Posted November 16, 2007 (edited) This is awesome, just what I was looking for, thanks! Edited November 16, 2007 by Ranmaru
AzKay Posted November 16, 2007 Posted November 16, 2007 Would there be a simpler version for the client? Like, You wrote a simpler version of the server. # MY LOVE FOR YOU... IS LIKE A TRUCK- #
zatorg Posted November 18, 2007 Author Posted November 18, 2007 Would there be a simpler version for the client?Like, You wrote a simpler version of the server.Hey,ooh, it has been a long time since I last visited these forums...Let me see. Which part don't you understand? I admit it's a bit confusing with all those new function names etc. Maybe I should comment on what the script does?
AzKay Posted November 19, 2007 Posted November 19, 2007 I just want to use the functions as a simple simple TCP connection, Like, For basic testing purposes. Like, Connecting to a server, sending data, and receiving the response. # MY LOVE FOR YOU... IS LIKE A TRUCK- #
zatorg Posted November 19, 2007 Author Posted November 19, 2007 Right, will try if I find some time. And that's either NOW or Saturday, cause will be totally N/A all this week.
zatorg Posted November 19, 2007 Author Posted November 19, 2007 OK, here's a PoC but it's not tested cause my Windows is going nuts. Will prob switch to OS X Leopard some time soon expandcollapse popup#include <ASock.au3> Const $MYMSG = 1024 Global $bConnectResult = 0 Global $hSocket = -1 ;;; Const $IP2CONNECT2 = "127.0.0.1" Const $PORT2CONNECT2 = 42775 ;;; If Not TCPStartup( ) Then Exit 1 _StartConnecting( $IP2CONNECT2, $PORT2CONNECT2, "EventHandler" ) If @extended Then ConsoleWrite( "+> Connected IMMEDIATELY. You have a darn good connection..." & @CRLF ) Else; Wait for the result of the connection attempt. Do Sleep( 100 ) Until $bConnectResult <> 0; $bConnectResult = 0 => connecting // = 1 => connected // = -1 => failed EndIf If $bConnectResult = -1 Then ConsoleWrite( "+> FAILED to connect to " & $IP2CONNECT2 & ":" & $PORT2CONNECT2 & "." & @CRLF ) Else ConsoleWrite( "+> YAY, connected!!! :)" & @CRLF ) TCPSend( $hSocket, "Howdy!" ) ; Will catch any response in "EventHandler". You can, however, TCPRecv() but this will be the usual BLOCKING function. ; Thus, you shouldn't use TCPRecv() :) ; Do whatever you desire.... While $bConnectResult = 1 TCPSend( $hSocket, "Fl000d..." ) Sleep( 1000 ) WEnd EndIf TCPCloseSocket( $hSocket ) TCPShutdown( ) Exit 0 Func EventHandler _ ( _ $hWnd, _ ; Equals to $hNotifyGUI (see _StartConnecting()) $iMsgID, _ ; Equals to $MYMSG if it's coming from Winsock $WParam, _ ; Equals to $hSocket $LParam _ ; Mixture of an error encountered (if any) and the type of event ) Local $iError = _HiWord( $LParam ); If $iError = 0 then it means the event indicates a success Local $iEvent = _LoWord( $LParam ); The event: connected / failed to conenct / data received / perfect conditions to send / conn closed Local $sDataBuff If $iMsgID = $MYMSG Then; Winsock, not Windows GDI Switch $iEvent Case $FD_CONNECT If $iError <> 0 Then $bConnectResult = -1; Failed to connect. Else $bConnectResult = 1; Connected! EndIf Case $FD_WRITE If $iError <> 0 Then $bConnectResult = -1; Error related to TCPSend(), probably failed sending data. EndIf Case $FD_READ If $iError <> 0 Then $bConnectResult = -1; Failed while attempting to receive data. Else ; Data arrived! $sDataBuff = TCPRecv( $hSocket, 65536 ); 64K buffer ConsoleWrite( "+> " & $IP2CONNECT2 & " says: " & $sDataBuff & @CRLF ) EndIf Case $FD_CLOSE ConsoleWrite( "+> Connection _gracefully_ closed." & @CRLF ) $bConnectResult = -1 EndSwitch EndIf EndFunc Func _StartConnecting( $sIP, $iPort, $sFunc ) Local $hNotifyGUI $hSocket = _ASocket( ) If @error Then Return False Local $hNotifyGUI = GUICreate( "notify" ) _ASockSelect( $hSocket, $hNotifyGUI, $MYMSG, BitOR( $FD_READ, $FD_WRITE, $FD_CONNECT, $FD_CLOSE ) ) If @error Then Return False GUIRegisterMsg( $MYMSG, $sFunc ) _ASockConnect( $hSocket, $sIP, $iPort ) If @extended Then; Have connected IMMEDIATELY, no point in waiting for _ASockConnect() result SetExtended( 1 ) Return True EndIf ; Connection attempt issued. Return True EndFunc
AzKay Posted November 19, 2007 Posted November 19, 2007 Thanks :3 Ill test it, And work out the kinks x3 # MY LOVE FOR YOU... IS LIKE A TRUCK- #
AzKay Posted November 19, 2007 Posted November 19, 2007 Works great :3 Thanks. # MY LOVE FOR YOU... IS LIKE A TRUCK- #
karman Posted November 19, 2007 Posted November 19, 2007 wowow works great i finished my msn client using this^^ finally i can handle conversations and the msn socket at the same time.. i love you..have a great life
AzKay Posted November 20, 2007 Posted November 20, 2007 wowow works great i finished my msn client using this^^ finally i can handle conversations and the msn socket at the same time.. i love you..have a great lifeDo tell :3I tried a few days ago, Couldnt get the damn thing to login xD;; # MY LOVE FOR YOU... IS LIKE A TRUCK- #
Yorn Posted November 20, 2007 Posted November 20, 2007 (edited) Okay, what I'm looking for is a combination of these two. I'm working on it on my own, but I figured I'd see if anyone had any pointers or tips for me.Basically, I want to listen on a port and run the server, then, when the data comes through, I forward it to another port/IP. Then I wait for certain sequences of data to catch and trigger events in response. My idea is to make a bot, but not a cheating one, I play a GTA roleplaying game and want to create NPCs for questing in the game. You can learn more about the game mod at http://www.sa-mp.com but right now, they don't have NPCs for the RPG mod and if I could create NPCs that would quest, the game would be a blast.As far as actions go in the game, I'm not as concerned, it's more about interfacing my AI bot in to chat with the user, as well as trigger some "/" commands if the user says certain key phrases. Edited November 20, 2007 by Yorn
zatorg Posted November 24, 2007 Author Posted November 24, 2007 (edited) Hey, I'm back. I hope I can help you. It seems what you need to do is to listen on a socket, accept connections, receive data from those connections, connect to remote host(s) and forward them the data received. This is more or less like tunneling. If you have any specific questions, don't hesitate asking. Good luck!!! And thanks everyone for the warm comments Edited November 24, 2007 by zatorg
Yorn Posted November 28, 2007 Posted November 28, 2007 Thanks, but now I'm looking at reading memory addresses instead of trying to do UDP tunneling, the traffic is encrypted anyway. All I really want to know how to do is read where the program is storing the text, so this is not a big deal.
zatorg Posted November 28, 2007 Author Posted November 28, 2007 (edited) Oh, so this is what you want to do! Alright, good luck then. I suggest you using SoftICE to trace the program flow. It is also possible to search for a particular string etc. Edited November 28, 2007 by zatorg
ZoScr Posted December 3, 2007 Posted December 3, 2007 zatorg, Many thanks for your thorough, thoughtful and generous contribution! The UDF is exactly what I was looking for, and fills a key gap in AutoIt's built-in socket functionality. Thank you!
Paulchen Posted February 26, 2008 Posted February 26, 2008 I get the following errorD:\Data\Entw\AutoIt\TCPIP\server_.au3 (220) : ==> "long_ptr", "int_ptr" and "short_ptr" DllCall() types have been deprecated. Use "long*", "int*" and "short*" instead.: Local $aRet = DLLCall("Ws2_32.dll","int","getpeername","int",$SHOCKET, "ptr",DLLStructGetPtr($sockaddr),"int_ptr",DLLStructGetSize($sockaddr)) ...; AutoIt Help -> TCPRecvFunc SocketToIP($SHOCKET) Local $sockaddr = DLLStructCreate("short;ushort;uint;char[8]") Local $aRet = DLLCall("Ws2_32.dll","int","getpeername","int",$SHOCKET, _ "ptr",DLLStructGetPtr($sockaddr),"int_ptr",DLLStructGetSize($sockaddr)) If Not @error And $aRet[0] = 0 Then $aRet = DLLCall("Ws2_32.dll","str","inet_ntoa","int",DLLStructGetData($sockaddr,3)) If Not @error Then $aRet = $aRet[0] Else $aRet = "(Could not get the address)" EndIf $sockaddr = 0 Return $aRetEndFunc....i have found the following descriptionhttp://www.autoitscript.com/forum/index.ph...opic=56168&can somebody help me to eliminate this?server_.au3
rover Posted February 26, 2008 Posted February 26, 2008 I get the following error D:\Data\Entw\AutoIt\TCPIP\server_.au3 (220) : ==> "long_ptr", "int_ptr" and "short_ptr" DllCall() types have been deprecated. Use "long*", "int*" and "short*" instead.: Local $aRet = DLLCall("Ws2_32.dll","int","getpeername","int",$SHOCKET, "ptr",DLLStructGetPtr($sockaddr),"int_ptr",DLLStructGetSize($sockaddr)) just change 'int_ptr' to ptr server.au3 with asock.au3 works for me in v3.2.8.1 and v3.2.11.1 from TCPRecv example in help file ; AutoIt Help -> TCPRecv Func SocketToIP($SHOCKET) Local $sockaddr, $aRet $sockaddr = DllStructCreate("short;ushort;uint;char[8]") $aRet = DllCall("Ws2_32.dll", "int", "getpeername", "int", $SHOCKET, _ "ptr", DllStructGetPtr($sockaddr), "ptr", DllStructGetSize($sockaddr)) If Not @error And $aRet[0] = 0 Then $aRet = DllCall("Ws2_32.dll", "str", "inet_ntoa", "int", DllStructGetData($sockaddr, 3)) If Not @error Then $aRet = $aRet[0] Else $aRet = 0 EndIf $sockaddr = 0 Return $aRet EndFunc ;==>SocketToIP I see fascists...
zatorg Posted November 29, 2009 Author Posted November 29, 2009 (edited) Hi zatorg Thanks a Ton for posting Asynchronous sockets UDF.I have been looking for this since from last 3 months . It's working fine for me, both the clients and the server. I have a doubt, I am having a client server application , where all the clients are connecting to the server .When they establish a connection they can start talk each other.Now it is totally based on TCP/IP. One loop is always monitoring the data's from the connected sockets.If anything comes it will process accordingly. If i change my server application by using Asynchronous sockets method will i be able to communicate between server and the clients. Because i am having 'n' number of clients. If possible can u tell me how can i implement the same.I have tried a lot but i am not able to figure out. Thanks & Regards Ajomon Hey Ajomon, I think that what you are basically looking at is an adaptation of the original example script <server.au3> which accepts multiple connections and then waits for Winsock to notify about events regarding those connections (e.g. in your case, you'd be interested in being notified about (and reading) received data as well as knowing which client in particular sent you that data -- and it's all in that script). http://www.autoitscript.com/forum/index....le=attach§ion=attach&attach_id=14413 (I hope this is reachable by all users; in any case, it's attached in this post: http://www.autoitscript.com/forum/index....?showtopic=45189&view=findpost&p=336722) I think that the original script will no longer work due to AutoIt language changes (unfortunately, I no longer have AutoIt around), but e.g. rover has addressed one of the issues here. On a very abstract level, what you need to do is to have an array of sockets (connection identifiers). When you establish all the connections with the clients (see source code of the script), you do whatever you want. Once data from a specific client is received, OnSocketEvent() is called. This line determines which client has sent the data (it is the socket number in your array of sockets): Local $nSocket = $iMsgID - $WM_USER - 1 In order for this to work, you have to previously inform WinSock that for each socket, you want to receive a specific ID ($iMsgID): (this is executed when a new connection has been accepted; on each such event, FreeSock() is called which returns the number of an unused element in the array of sockets) _ASockSelect( $hSockets[ $iFreeSock ], $hNotifyGUI, $WM_USER + $iFreeSock + 1, BitOR( $FD_READ, $FD_WRITE, $FD_CLOSE ) ) _ASockSelect() "registers" the socket in the sense that it tells Winsock to notify the program when certain events that interest us (in this case, receival of data, closure of the connection and perfect conditions to send data to that client (this last one is not that interesting)) take place. Notice the "$WM_USER + $iFreeSock + 1" part: $iFreeSock is the number of an unused element in the socket array ($iFreeSock stores the number returned by FreeSock()); "$WM_USER + 1" is needed because the notification process uses Windows Graphics Device callback mechanism; what this means is that the mechanism might send events unrelated to the socket concerned (it might be about the dummy GUI window needed to receive notifications from Winsock). Starting with a constant "WM_USER" + 1 (WM_USER is the last (biggest) constant still reserved for Winsock-unrelated events), you are free to choose a number that will be received by OnSocketEvent(). In this script, the number is basically the socket's in question position in the array. Perhaps you can tell why your current implementation (which, as I understand, uses AutoIt's built-in socket functions) does not satisfy you? I gather you want to do more useful stuff (e.g. handle the GUI) rather than just poll for socket events which Winsock can do for you? If so, then maybe you just need to adapt the script <server.au3> - if I'm totally wrong, maybe you can paste relevant excerpts of your code here/somewhere that we can look at. Edit: oh, sorry, I haven't actually answered your question - yes (see server.au3 - the part in OnSocketEvent() where there is a TrayTip displayed telling what and from where was received - you could simply change that line(s) to TCPSend($hSocket, "response data")) Edit 2: I also forgot to mention that in order to "register" a socket, you also need to GUIRegisterMsg($id_to_use, "FunctionName"): For $i = 0 To $N_MAXSOCKETS - 1 $hSockets[ $i ] = -1 GUIRegisterMsg( $WM_USER + 1 + $i, "OnSocketEvent" ) Next In this script, it is done before any actual socket operations (listening etc.) are performed. Edited November 29, 2009 by zatorg
Tr4d3r Posted February 14, 2010 Posted February 14, 2010 Hello, excelent piece of code ... i already use it on many proyects ... But, i have a problem when this is performed by a Service AutoIT application ... the message never are received... I Can see in the server part that the client connect, but in the client, the event never is fired ... i think is because in the system account, there is not a visible desktop ... Any idea to make a event RECEIVED running inthe system desktop as a service? Thanks a lot. Tr4d3r
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