Sign in to follow this  
Followers 0
nullschritt

TCP P2P, Event Driven Udf (Better!)

12 posts in this topic

#1 ·  Posted (edited)

Hello, I am re-releasing hyperzap's Event Driven P2P UDF with some modifications.

Thanks to hyperzap for the original UDF.
 
New Features

  • Dynamic RegEx Headers/Footers
  • Supports Messages of Any Length (Including file transfers) [automatically]
  • Allows use of all symbols/letters in messages*

Pre-Modification Features

  • Relays messages over P2P network
  • Delivers messages to client only machines [that cannot port forward]
  • BootStrapping (optional) [Automatically connect to more peers]
  • Even Driven
  • LAN or WAN Mode
  • FAST (Takes 5-50ms per hop)

Known Limitations

  • Does not relay messages when emulated on linux with WINE. (still receives and sends messages)

* = You CANNOT use the "`" symbol in long range messages. To support this symbol, please replace it with it's html entity, urlencode, or use the INCLUDED _base64encode function on data you want to send long range.
 


How it works:
##################
When you start the UDF, it will start listening and accepting incoming connections. The UDF will, in the backround, continue to manage all your connections and initiate any new ones should you use the _P2P_Connect( IP) function. It will also manage the recieving and sending of data.
As a P2P node should, it will route data destined for others, and it will also maintain a healthy number of connections (the number which you define when you start the node).

This entire system is event driven, so you will register your functions with the UDF and the function will get called when the corresponding event happens. See the comments in the UDF for more information.
This works in the same way as Kip's TCP UDF.


Structure:
##################
The first thing you must do is start the Node:
_P2P_Start_Node( Node Identifier, Port, Max peers, Bootstrap mode, Bootstrap max, local/global, IP)

All the Parameters are pretty self expanatory. The Node identifier is the name of your computer in the network. It must not change across sessions and it must be unique. It is used to identify you in your network.

Bootstrapping means autoconnecting. if Bootstrap mode is 1, It will autoconnect you to others until you reach your Bootstrap Max.

Local/Global - Put 0 if working on a LAN, 1 if over internet.

IP - (Optional). You shouldn't need to change this. It is the IP of the listening port.

The second thing is declare your functions. This tells the UDF which functions to call when something happens. EG:
_P2P_Register_Event($P2P_RECEIVE, "my_recieve_function")
So, this will call the function my_recieve_function when data from a peer is recieved. See the comments at the beginning of the UDF for a complete list of Event values, and the parameters for your functions.

Then fire away!
_P2P_Send( $socket, "MY DATA!!)
_P2P_Connect( "127.0.0.1")
_P2P_Broadcast( "My data")

When your done,

_P2P_Stop_Node()

The UDF:

#cs ----------------------------------------------------------------------------

 AutoIt Version: 3.3.0.0
 Author:         Hyperzap.
 Modified By: NullSchritt (Stormageddon)
                 Design concepts were first coined by Kip in his "Event driven TCP UDF"
                 Zatorg's Asynchronous Sockets UDF is also used.
 Script Function:
 
    This UDF is a re-write of Kip's 'Event driven TCP UDF'. Thx Kip.
    It aims to generate simple TCP, event driven functionality for P2P programs, As
    opposed to client-server oriented communication as in Kip's UDF.
    Evidently, this functionality is not possible in Kips original releases.
    
    Apart from the obvious conponents of such a code, like Recv, Send, Connect,
    Listen, other important P2P routines have been coded. These include things 
    like; Universal identifiers, bootstrapping mechanisms, peers
    discovery, and message routing.
    
    MINOR DRAWBACKS:
    You must replace "`" in messages with it's html entity or some other 
    symbol during long range message routing.
#ce ----------------------------------------------------------------------------

$UDF_Version = "1.33 STABLE"
$console_out = False
$STANDARD_MESSAGE_LIFE = 200
#cs
Functions:

    _P2P_Start_Node( Node Identifier, Port, Max peers, Bootstrap mode, Boostrap max, local/global, IP)
    _P2P_Stop_Node()
    _P2P_Connect( IP)
    _P2P_Send( Socket, Data)
    _P2P_Disconnect_Peer( Socket)
    _P2P_Send_Message( Address, Data)
    
    _P2P_Register_Event($iEvent, $sFunction)


Register event values:

    $P2P_AUX_DATA           ; Function ($hSocket, $DataType, $Data);When things like IP and Node identifier are discovered.
    $P2P_MESSAGE            ; Function ($hSocket, $message, $iError) ;When long distance messages are recieved.
    $P2P_RECEIVE            ; Function ($hSocket, $sReceived, $iError)
    $P2P_CONNECT            ; Function ($hSocket, $iError)                  
    $P2P_DISCONNECT         ; Function ($hSocket, $iError)
    $P2P_NEWCONNECTION      ; Function ($hSocket, $iError) 



   Also, please call the function  peer_broadcast() periodically in your program. Failing to do this will
   Seriously cripple the bootstrapping mechanism (unless you program is ALWAYS recieving data at least once
   every 40 seconds, In which case the mechanism will trigger automatically).
#ce

Global Const $fd_read = 1
Global Const $fd_write = 2
Global Const $fd_oob = 4
Global Const $fd_accept = 8
Global Const $fd_connect = 16
Global Const $fd_close = 32
Global $hws2_32 = -1
Global Const $tcp_send = 1
Global Const $tcp_receive = 2
Global Const $tcp_connect = 4
Global Const $tcp_disconnect = 8
Global Const $tcp_newclient = 16
Global Const $iploc_local = 64
Global Const $iploc_global = 128
Global Const $p2p_message = 256
Global Const $p2p_receive = 512
Global Const $p2p_connect = 1024
Global Const $p2p_disconnect = 2048
Global Const $p2p_newconnection = 4096
Global Const $p2p_aux_data = 8192
Global $total_connected = 0
Global $max_connections
Global $listening_socket
Global $node_ip
Global $node_port
Global $node_identifier
Global $node_ext_ip
Global $bootstrap_mode
Global $bootstrap_max
Global $peer_timer
Global $total_id_known = 0
Global $known_id[200]
Global $connectfunc = ""
Global $recievefunc = ""
Global $disconnectfunc = ""
Global $newconnectionfunc = ""
Global $messagefunc = ""
Global $auxfunc = ""
Global $main_socket_address = ""
TCPStartup()
Global Const $__tcp_window = GUICreate("Async Sockets UDF")

Func _p2p_start_node($node_id, $port, $max_peers, $bootstrapmode, $bootstrapmax, $location, $ip = "0.0.0.0")
    Local $startuptimer = TimerInit()
    $listening_socket = ___asocket()
    $main_socket_address = $listening_socket
    ___asockselect($listening_socket, $__tcp_window, 1024, $fd_accept)
    GUIRegisterMsg(1024, "Listensocket_data_")
    ___asocklisten($listening_socket, $ip, $port)
    If $bootstrapmode = 0 Then $bootstrap_mode = $iploc_local
    If $bootstrapmode = 1 Then $bootstrap_mode = $iploc_global
    $bootstrap_max = $bootstrapmax
    $max_connections = $max_peers
    $node_ip = $ip
    $node_port = $port
    $node_identifier = $node_id
    $peer_timer = TimerInit()
    If $location = 1 Then $node_ext_ip = _get_ip()
    If $location = 0 Then $node_ext_ip = @IPAddress1
    Global $socket_handle_array[$max_peers + 1]
    Global $node_identifier_array[$max_peers + 1]
    Global $node_ip_array[$max_peers + 1]
    Global $node_peer_reachable_list[$max_peers + 1]
    For $x = 0 To $max_peers Step 1
        $socket_handle_array[$x] = -1
        $node_identifier_array[$x] = -1
        $node_ip_array[$x] = -1
        $node_peer_reachable_list[$x] = -1
    Next
    If $console_out = True Then ConsoleWrite(@CRLF & @CRLF & "P2P_: Node started")
    If $console_out = True Then ConsoleWrite(@CRLF & "P2P_: Port: " & $node_port)
    If $console_out = True Then ConsoleWrite(@CRLF & "P2P_: Ext IP: " & $node_ext_ip)
    If $console_out = True Then ConsoleWrite(@CRLF & "P2P_: Max peers: " & $max_connections)
    If $console_out = True Then ConsoleWrite(@CRLF & "P2P_: Identifier: " & $node_identifier)
    If $console_out = True Then ConsoleWrite(@CRLF & "P2P_: Engine Version: " & $udf_version)
    If $console_out = True Then ConsoleWrite(@CRLF & "P2P_: Startup time: " & TimerDiff($startuptimer) & "ms" & @CRLF)
EndFunc

Func _p2p_stop_node()
    ___asockshutdown($listening_socket)
    TCPCloseSocket($listening_socket)

        $socket_handle_array= -1
        $node_identifier_array= -1
        $node_ip_array= -1
        $node_peer_reachable_list= -1
    $max_connections = 0
    $listening_socket = ""
    $node_ip = ""
    $node_port = ""
    $node_identifier = -1
    $node_ext_ip = ""
    $bootstrap_mode = ""
    $bootstrap_max = 0
    $connectfunc = ""
    $recievefunc = ""
    $disconnectfunc = ""
    $newconnectionfunc = ""
    $messagefunc = ""
    $auxfunc = ""
    If $console_out = True Then ConsoleWrite(@CRLF & "P2P_: Engine shutdown successful.")
EndFunc

Func listensocket_data_($hwnd, $imsgid, $wparam, $lparam)
    Local $socketinquestion = $wparam
    Local $ierror = ___hiword($lparam)
    Local $ievent = ___loword($lparam)
    Abs($hwnd)
    If $imsgid = 1024 Then
        If $ievent = $fd_accept Then
            If NOT $ierror Then
                $arrayslot = findfreearrayslot()
                If $arrayslot = "error" Then
                    $newsocket = TCPAccept($socketinquestion)
                    TCPSend($newsocket, "`" & _generateheader(2) & "`NOSLOT`" & _generateheader(1))
                    TCPCloseSocket($newsocket)
                EndIf
                $newsocket = TCPAccept($socketinquestion)
                ___asockselect($newsocket, $__tcp_window, 1024 + $arrayslot, BitOR($fd_read, $fd_connect, $fd_close))
                GUIRegisterMsg(1024 + $arrayslot, "Opensocket_data_")
                $socket_handle_array[$arrayslot] = $newsocket
                $node_identifier_array[$arrayslot] = -1
                $node_ip_array[$arrayslot] = -1
                TCPSend($newsocket, "`" & "`IP`" & $node_ext_ip & _generateheader(1))
                TCPSend($newsocket, "`" & "`ID`" & $node_identifier & _generateheader(1))
                peer_broadcast_to_peer($newsocket)
                $total_connected += 1
                Call($newconnectionfunc, $newsocket, $ierror)
            Else
                Call($newconnectionfunc, 0, $ierror)
            EndIf
        ElseIf $ievent = $fd_connect Then
            Call($connectfunc, $newsocket, $ierror)
        EndIf
    EndIf
EndFunc

Func _generateheader($type = 1)
    $alpha = StringSplit("PRODY", "", 3)
    $str = ""
    If $type = 1 Then
        $str = "--P2P:"
        For $i = 1 To 5
            $str &= Random(0, 9, 1) & $alpha[Random(0, 4, 1)]
        Next
        Return $str
    EndIf
    If $type = 2 Then
        $str = "--P2P:"
        For $i = 1 To 5
            $str &= $alpha[Random(0, 4, 1)] & Random(0, 9, 1)
        Next
        Return $str
    EndIf
EndFunc

Func findfreearrayslot()
    $newconnnum = -1
    For $x = 1 To $max_connections
        If $socket_handle_array[$x] = -1 Then
            $newconnnum = $x
            ExitLoop
        EndIf
    Next
    If $newconnnum = -1 Then Return "error"
    Return $newconnnum
EndFunc

Func opensocket_data_($hwnd, $imsgid, $wparam, $lparam)
    Local $ierror = ___hiword($lparam)
    Local $ievent = ___loword($lparam)
    Abs($hwnd)
    Local $array_slot = $imsgid - 1024
    Local $socketid = $socket_handle_array[$array_slot]
    If $socketid = -1 Then Return 0
    Switch $ievent
        Case $fd_read
            $rawrecv = TCPRecv($socketid, 2048)
            If $rawrecv <> "" Then
                $regex = StringRegExp($rawrecv, "--P2P:([0-9](.*?)[PRODY]){5}", 2)
                If IsArray($regex) Then
                    $rawrecv = StringReplace($rawrecv, $regex[0], "")
                    recvprocess($rawrecv, $socketid, $array_slot, $ierror)
                Else
                    $dre = 0
                    Do
                        $recvtmp = TCPRecv($socketid, 2048)
                        If $recvtmp = "" Then
                            ExitLoop
                        EndIf
                        $rawrecv &= $recvtmp
                        $regex = StringRegExp($rawrecv, "--P2P:([0-9](.*?)[PRODY]){5}", 2)
                        Sleep(1)
                    Until IsArray($regex)
                    If IsArray($regex) Then
                        $rawrecv = StringReplace($rawrecv, $regex[0], "")
                        recvprocess($rawrecv, $socketid, $array_slot, $ierror)
                    EndIf
                EndIf
            EndIf
        Case $fd_close
            ___asockshutdown($socketid)
            TCPCloseSocket($socketid)
            Call($disconnectfunc, $socketid, $ierror)
            $socket_handle_array[$array_slot] = -1
            $node_identifier_array[$array_slot] = -1
            $node_ip_array[$array_slot] = -1
            $node_peer_reachable_list[$array_slot] = -1
            $total_connected -= 1
            If TimerDiff($peer_timer) > 40000 Then
                peer_broadcast()
            EndIf
        Case $fd_connect
            If $ierror Then
                If $console_out = True Then ConsoleWrite(@CRLF & "P2P_: Connection failed: " & $socketid)
                $socket_handle_array[$array_slot] = -1
                $node_identifier_array[$array_slot] = -1
                $node_ip_array[$array_slot] = -1
                $node_peer_reachable_list[$array_slot] = -1
                $total_connected -= 1
                Call($connectfunc, $socketid, $ierror)
            Else
                Call($connectfunc, $socketid, $ierror)
                If $console_out = True Then ConsoleWrite(@CRLF & "P2P_: Connection established: " & $socketid)
                TCPSend($socket_handle_array[$array_slot], "`" & "`IP`" & $node_ext_ip & _generateheader(1))
                TCPSend($socket_handle_array[$array_slot], "`" & "`ID`" & $node_identifier & _generateheader(1))
                peer_broadcast_to_peer($socket_handle_array[$array_slot])
            EndIf
            If TimerDiff($peer_timer) > 40000 Then
                peer_broadcast()
            EndIf
    EndSwitch
EndFunc

Func recvprocess($rawrecv, $socketid, $array_slot, $ierror)
    If StringLen($rawrecv) < 1 Then Return 0
    $regex = StringRegExp($rawrecv, "--P2P:([0-9](.*?)[PRODY]){5}", 2)
    If IsArray($regex) Then
        Local $single_data = StringSplit($rawrecv, $regex[0], 1)
    Else
        Local $single_data = $rawrecv
    EndIf
    If UBound($single_data) < 1 Then Return 
    For $k = 1 To $single_data[0] Step 1
        If $single_data[$k] = "" Then ContinueLoop
        If $single_data[$k] = " " Then ContinueLoop
        If StringRegExp($single_data[$k], "--P2P:([PRODY](.*?)[0-9]){5}") Then
            node_data_process($socketid, $single_data[$k], $array_slot, $ierror)
        Else
            Call($recievefunc, $socketid, $single_data[$k], $ierror)
        EndIf
    Next
    If TimerDiff($peer_timer) > 40000 Then
        peer_broadcast()
    EndIf
EndFunc

Func node_data_process($socketid, $data, $array_slot, $ierror)
    Local $split = StringSplit($data, "`")
    If $split[3] = "IP" Then
        $node_ip_array[$array_slot] = $split[4]
        Call($auxfunc, $socketid, "IP", $split[4])
    EndIf
    If $split[3] = "ID" Then
        $node_identifier_array[$array_slot] = $split[4]
        Call($auxfunc, $socketid, "ID", $split[4])
    EndIf
    If $split[3] = "PEER" Then bootstrap($socketid, $split[4], $array_slot, $ierror)
    If $split[3] = "IDLIST" Then
        $node_peer_reachable_list[$array_slot] = $split[4]
        Call($auxfunc, $socketid, "NODE-REACHABLE", $split[4])
    EndIf
    If $split[3] = "MESSAGE" Then
        route_message($socketid, $data, $array_slot)
    EndIf
EndFunc

Func bootstrap($socketid, $split, $array_slot, $ierror)
    If $bootstrap_mode = $iploc_local Then Return 9
    If $total_connected >= $bootstrap_max Then Return 8
    Local $connectpeers = Round(($bootstrap_max / $total_connected / 2), 0)
    If $connectpeers < $bootstrap_max AND $connectpeers = 0 Then $connectpeers = 1
    If $console_out = True Then ConsoleWrite(@CRLF & "P2P_: Bootstrap stats: " & $connectpeers & ":" & $total_connected & "/" & $bootstrap_max)
    $peers = StringSplit($split, ";")
    For $d = 1 To $connectpeers Step 1
        $error = False
        $rndarray = Random(1, $peers[0], 1)
        If $peers[$rndarray] = "" OR $peers[$rndarray] = " " Then ContinueLoop
        For $u = 0 To $max_connections Step 1
            If $peers[$rndarray] = $node_ip_array[$u] Then
                If $console_out = True Then ConsoleWrite(@CRLF & "P2P_: Bootstrap: connectee already connected! reselecting...")
                $error = True
                ExitLoop
            EndIf
        Next
        If $error = True Then ContinueLoop
        _p2p_connect($peers[$rndarray])
    Next
EndFunc

Func peer_broadcast()
    $peer_timer = TimerInit()
    Local $peers = ""
    Local $idlist = ""
    For $a = 0 To $max_connections Step 1
        If $node_ip_array[$a] <> -1 Then $peers &= $node_ip_array[$a] & ";"
        If $node_identifier_array[$a] <> -1 Then $idlist &= $node_identifier_array[$a] & ";"
    Next
    _p2p_broadcast("`" & _generateheader(2) & "`PEER`" & $peers)
    _p2p_broadcast("`" & _generateheader(2) & "`IDLIST`" & $idlist)
EndFunc

Func peer_broadcast_to_peer($socket)
    Local $peers = ""
    Local $idlist = ""
    For $a = 0 To $max_connections Step 1
        If $node_ip_array[$a] <> -1 Then $peers &= $node_ip_array[$a] & ";"
        If $node_identifier_array[$a] <> -1 Then $idlist &= $node_identifier_array[$a] & ";"
    Next
    TCPSend($socket, "`" & _generateheader(2) & "`PEER`" & $peers & _generateheader(1))
    TCPSend($socket, "`" & _generateheader(2) & "`IDLIST`" & $idlist & _generateheader(1))
EndFunc

Func route_message($socket, $message, $array_slot)
    If $console_out = True Then ConsoleWrite(@CRLF & "P2P_: MessageRouting started")
    Local $timer = TimerInit()
    Local $split = StringSplit($message, "`")
    If $split[0] < 6 Then Return 1
    Local $ttl = $split[4]
    Local $from = $split[5]
    Local $address = $split[6]
    Local $identifier = $split[7]
    Local $begin = "`" & _generateheader(2) & "`MESSAGE`" & $ttl & "`" & $from & "`" & $address & "`" & $identifier & "`"
    Local $cutlen = StringLen($message) - StringLen($begin)
    If idknown($split[7]) = True Then
        If $console_out = True Then ConsoleWrite(@CRLF & "P2P_: Message-ID known.")
        If $console_out = True Then ConsoleWrite(@CRLF & "P2P_: Message Routing Finished: " & Round(TimerDiff($timer), 1))
        Return 1
    EndIf
    If $address = $node_identifier Then
        Local $messagetrim = StringRight($message, $cutlen)
        Local $messagetrim = StringRight($message, $cutlen)
        If $console_out = True Then ConsoleWrite(@CRLF & "P2P_: Message-Inbound")
        If $console_out = True Then ConsoleWrite(@CRLF & "P2P_: Message Routing Finished: " & Round(TimerDiff($timer), 1))
        Call($messagefunc, $socket, $messagetrim, $from, 0)
        Return 1
    EndIf
    If $ttl = 0 Then
        If $console_out = True Then ConsoleWrite(@CRLF & "P2P_: Message-TTL Exceeded.")
        If $console_out = True Then ConsoleWrite(@CRLF & "P2P_: Message Routing Finished: " & Round(TimerDiff($timer), 1))
        Return 1
    EndIf
    $messagefull = "`" & _generateheader(2) & "`MESSAGE`" & ($ttl - 1) & "`" & $from & "`" & $address & "`" & $identifier & "`" & StringRight($message, $cutlen)
    If $console_out = True Then ConsoleWrite(@CRLF & "P2P_: Starting First level Routing: " & $total_connected)
    For $qwe = 0 To $max_connections Step 1
        If $address = $node_identifier_array[$qwe] Then
            _p2p_send($socket_handle_array[$qwe], $messagefull)
            If $console_out = True Then ConsoleWrite(@CRLF & "P2P_: Message-Destination located.")
            If $console_out = True Then ConsoleWrite(@CRLF & "P2P_: Message Routing Finished: " & Round(TimerDiff($timer), 1))
            Return 1
        EndIf
    Next
    If $socket = -1 Then
        _p2p_broadcast($messagefull)
        If $console_out = True Then ConsoleWrite(@CRLF & "P2P_: Message Routing Finished: " & Round(TimerDiff($timer), 1))
        Return 1
    Else
        For $qwe = 0 To $max_connections Step 1
            If $socket_handle_array[$qwe] = -1 Then ContinueLoop
            If StringInStr($node_peer_reachable_list[$qwe], $address) > 0 Then
                _p2p_send($socket_handle_array[$qwe], $messagefull)
                If $console_out = True Then ConsoleWrite(@CRLF & "P2P_: Message-2nd Level destination located. ")
                If $console_out = True Then ConsoleWrite(@CRLF & "P2P_: Message Routing Finished: " & Round(TimerDiff($timer), 1))
                Return 1
            EndIf
        Next
    EndIf
    For $qwe = 0 To $max_connections Step 1
        If $socket_handle_array[$qwe] = -1 Then ContinueLoop
        If $node_identifier_array[$qwe] = $node_identifier_array[$array_slot] Then ContinueLoop
        If StringInStr($node_peer_reachable_list[$array_slot], $node_identifier_array[$qwe]) > 0 Then ContinueLoop
        _p2p_send($socket_handle_array[$qwe], $messagefull)
    Next
    If $console_out = True Then ConsoleWrite(@CRLF & "P2P_: Message Routing Finished: " & Round(TimerDiff($timer), 1))
EndFunc

Func _p2p_send_message($idaddress, $indata, $from = "Null")
    Local $messageid = Round(((Random(0, 99999999999, 1) * @YDAY) / @MIN) * (Random(5, 1376, 1) / (@SEC * 100)), 0)
    Local $ttl = $standard_message_life
    Local $fullmessage = "`" & _generateheader(2) & "`MESSAGE`" & $ttl & "`" & $from & "`" & $idaddress & "`" & $messageid & "`" & $indata & _generateheader(1)
    If $console_out = True Then ConsoleWrite(@CRLF & "P2P_: Message generated: " & $messageid)
    route_message(-1, $fullmessage, -1)
EndFunc

Func idknown($id)
    For $idcount = 0 To $total_id_known Step 1
        If $known_id[$idcount] = $id Then Return True
    Next
    $total_id_known += 1
    If $total_id_known > 198 Then $total_id_known = 0
    $known_id[$total_id_known] = $id
    Return False
EndFunc

Func _p2p_send($socket, $data)
    TCPSend($socket, $data & _generateheader(1))
EndFunc

Func _p2p_disconnect_peer($socket)
    Local $it_socket = ""
    Local $array_slot = ""
    For $count = 0 To $max_connections Step 1
        If $socket_handle_array[$count] = $socket Then
            $it_socket = $socket
            $array_slot = $count
            ExitLoop
        EndIf
    Next
    If $it_socket = "" Then Return False
    ___asockshutdown($it_socket)
    TCPCloseSocket($it_socket)
    $socket_handle_array[$array_slot] = -1
    $node_identifier_array[$array_slot] = -1
    $node_ip_array[$array_slot] = -1
    $node_peer_reachable_list[$array_slot] = -1
    If $console_out = True Then ConsoleWrite(@CRLF & "P2P_: Peer " & $it_socket & " closed.")
    Return True
EndFunc

Func _p2p_connect($conn_ip)
    For $u = 0 To $max_connections Step 1
        If $conn_ip = $node_ip_array[$u] Then
            If $console_out = True Then ConsoleWrite(@CRLF & "P2P_: Unable to connect-IP is already connected!")
            Return 1
        EndIf
    Next
    If $conn_ip = "" Then Return 0
    If $conn_ip = " " Then Return 0
    If $conn_ip = "0" Then Return 0
    If $conn_ip = ";" Then Return 0
    If $conn_ip = @CRLF Then Return 0
    $arrayslot = findfreearrayslot()
    If $arrayslot = "error" Then
        If $listening_socket = "" Then
            If $console_out = True Then ConsoleWrite(@CRLF & "P2P_: Unable to connect-node services offline!")
            Return 3
        EndIf
        If $console_out = True Then ConsoleWrite(@CRLF & "P2P_: Unable to connect-peer limit reached!")
        Return 2
    EndIf
    If $console_out = True Then ConsoleWrite(@CRLF & "P2P_: Attempting Connection: " & $conn_ip)
    Local $socketid = ___asocket()
    ___asockselect($socketid, $__tcp_window, 1024 + $arrayslot, BitOR($fd_connect, $fd_read, $fd_close))
    GUIRegisterMsg(1024 + $arrayslot, "Opensocket_data_")
    $socket_handle_array[$arrayslot] = $socketid
    $node_identifier_array[$arrayslot] = -1
    $node_ip_array[$arrayslot] = $conn_ip
    $return = ___asockconnect($socketid, $conn_ip, $node_port)
    $total_connected += 1
    If @extended Then
        If $console_out = True Then ConsoleWrite(@CRLF & "_P2P: Connection Established.")
        Call($connectfunc, $socketid, 0)
    EndIf
EndFunc

Func _p2p_broadcast($data)
    Local $i
    For $i = 0 To $max_connections Step 1
        If $socket_handle_array[$i] <> -1 Then TCPSend($socket_handle_array[$i], $data & _generateheader(1))
    Next
    Return True
EndFunc

Func _p2p_peerlist()
    Local $alist[$max_connections + 1][3], $alist_count = 1
    For $i = 1 To $max_connections
        If $socket_handle_array[$i] <> -1 Then
            $alist[$alist_count][0] = $socket_handle_array[$i]
            $alist[$alist_count][1] = $node_identifier_array[$i]
            $alist[$alist_count][2] = $node_ip_array[$i]
            $alist_count += 1
        EndIf
    Next
    $alist[0][0] = $alist_count
    Return $alist
EndFunc

Func _p2p_register_event($ievent, $sfunction)
    If $ievent = $p2p_aux_data Then $auxfunc = $sfunction
    If $ievent = $p2p_receive Then $recievefunc = $sfunction
    If $ievent = $p2p_connect Then $connectfunc = $sfunction
    If $ievent = $p2p_disconnect Then $disconnectfunc = $sfunction
    If $ievent = $p2p_newconnection Then $newconnectionfunc = $sfunction
    If $ievent = $p2p_message Then $messagefunc = $sfunction
EndFunc

Func ___asocket($iaddressfamily = 2, $itype = 1, $iprotocol = 6)
    If $hws2_32 = -1 Then $hws2_32 = DllOpen("Ws2_32.dll")
    Local $hsocket = DllCall($hws2_32, "uint", "socket", "int", $iaddressfamily, "int", $itype, "int", $iprotocol)
    If @error Then
        SetError(1, @error)
        Return -1
    EndIf
    If $hsocket[0] = -1 Then
        SetError(2, ___wsagetlasterror())
        Return -1
    EndIf
    Return $hsocket[0]
EndFunc

Func ___asockshutdown($hsocket)
    If $hws2_32 = -1 Then $hws2_32 = DllOpen("Ws2_32.dll")
    Local $iret = DllCall($hws2_32, "int", "shutdown", "uint", $hsocket, "int", 2)
    If @error Then
        SetError(1, @error)
        Return False
    EndIf
    If $iret[0] <> 0 Then
        SetError(2, ___wsagetlasterror())
        Return False
    EndIf
    Return True
EndFunc

Func ___asockclose($hsocket)
    If $hws2_32 = -1 Then $hws2_32 = DllOpen("Ws2_32.dll")
    Local $iret = DllCall($hws2_32, "int", "closesocket", "uint", $hsocket)
    If @error Then
        SetError(1, @error)
        Return False
    EndIf
    If $iret[0] <> 0 Then
        SetError(2, ___wsagetlasterror())
        Return False
    EndIf
    Return True
EndFunc

Func ___asockselect($hsocket, $hwnd, $uimsg, $ievent)
    If $hws2_32 = -1 Then $hws2_32 = DllOpen("Ws2_32.dll")
    Local $iret = DllCall($hws2_32, "int", "WSAAsyncSelect", "uint", $hsocket, "hwnd", $hwnd, "uint", $uimsg, "int", $ievent)
    If @error Then
        SetError(1, @error)
        Return False
    EndIf
    If $iret[0] <> 0 Then
        SetError(2, ___wsagetlasterror())
        Return False
    EndIf
    Return True
EndFunc

Func ___asocklisten($hsocket, $sip, $uiport, $imaxpending = 5)
    Local $iret
    Local $staddress
    If $hws2_32 = -1 Then $hws2_32 = DllOpen("Ws2_32.dll")
    $staddress = ___sockaddr($sip, $uiport)
    If @error Then
        SetError(@error, @extended)
        Return False
    EndIf
    $iret = DllCall($hws2_32, "int", "bind", "uint", $hsocket, "ptr", DllStructGetPtr($staddress), "int", DllStructGetSize($staddress))
    If @error Then
        SetError(3, @error)
        Return False
    EndIf
    If $iret[0] <> 0 Then
        $staddress = 0
        SetError(4, ___wsagetlasterror())
        Return False
    EndIf
    $iret = DllCall($hws2_32, "int", "listen", "uint", $hsocket, "int", $imaxpending)
    If @error Then
        SetError(5, @error)
        Return False
    EndIf
    If $iret[0] <> 0 Then
        $staddress = 0
        SetError(6, ___wsagetlasterror())
        Return False
    EndIf
    Return True
EndFunc

Func ___asockconnect($hsocket, $sip, $uiport)
    Local $iret
    Local $staddress
    If $hws2_32 = -1 Then $hws2_32 = DllOpen("Ws2_32.dll")
    $staddress = ___sockaddr($sip, $uiport)
    If @error Then
        SetError(@error, @extended)
        Return False
    EndIf
    $iret = DllCall($hws2_32, "int", "connect", "uint", $hsocket, "ptr", DllStructGetPtr($staddress), "int", DllStructGetSize($staddress))
    If @error Then
        SetError(3, @error)
        Return False
    EndIf
    $iret = ___wsagetlasterror()
    If $iret = 10035 Then
        Return True
    EndIf
    SetExtended(1)
    Return True
EndFunc

Func ___sockaddr($sip, $iport, $iaddressfamily = 2)
    Local $iret
    Local $staddress
    If $hws2_32 = -1 Then $hws2_32 = DllOpen("Ws2_32.dll")
    $staddress = DllStructCreate("short; ushort; uint; char[8]")
    If @error Then
        SetError(1, @error)
        Return False
    EndIf
    DllStructSetData($staddress, 1, $iaddressfamily)
    $iret = DllCall($hws2_32, "ushort", "htons", "ushort", $iport)
    DllStructSetData($staddress, 2, $iret[0])
    $iret = DllCall($hws2_32, "uint", "inet_addr", "str", $sip)
    If $iret[0] = -1 Then
        $staddress = 0
        SetError(2, ___wsagetlasterror())
        Return False
    EndIf
    DllStructSetData($staddress, 3, $iret[0])
    Return $staddress
EndFunc

Func ___wsagetlasterror()
    If $hws2_32 = -1 Then $hws2_32 = DllOpen("Ws2_32.dll")
    Local $iret = DllCall($hws2_32, "int", "WSAGetLastError")
    If @error Then
        SetExtended(1)
        Return 0
    EndIf
    Return $iret[0]
EndFunc

Func ___makelong($loword, $hiword)
    Return BitOR($hiword * 65536, BitAND($loword, 65535))
EndFunc

Func ___hiword($long)
    Return BitShift($long, 16)
EndFunc

Func ___loword($long)
    Return BitAND($long, 65535)
EndFunc

Func _get_ip()
    Local $ip, $t_ip
    If InetGet("http://checkip.dyndns.org/?rnd1=" & Random(1, 65536) & "&rnd2=" & Random(1, 65536), @TempDir & "\~ip.tmp") Then
        $ip = FileRead(@TempDir & "\~ip.tmp", FileGetSize(@TempDir & "\~ip.tmp"))
        FileDelete(@TempDir & "\~ip.tmp")
        $ip = StringTrimLeft($ip, StringInStr($ip, ":") + 1)
        $ip = StringTrimRight($ip, StringLen($ip) - StringInStr($ip, "/") + 2)
        $t_ip = StringSplit($ip, ".")
        If $t_ip[0] = 4 AND StringIsDigit($t_ip[1]) AND StringIsDigit($t_ip[2]) AND StringIsDigit($t_ip[3]) AND StringIsDigit($t_ip[4]) Then
            Return $ip
        EndIf
    EndIf
    If InetGet("http://www.whatismyip.com/?rnd1=" & Random(1, 65536) & "&rnd2=" & Random(1, 65536), @TempDir & "\~ip.tmp") Then
        $ip = FileRead(@TempDir & "\~ip.tmp", FileGetSize(@TempDir & "\~ip.tmp"))
        FileDelete(@TempDir & "\~ip.tmp")
        $ip = StringTrimLeft($ip, StringInStr($ip, "Your ip is") + 10)
        $ip = StringLeft($ip, StringInStr($ip, " ") - 1)
        $ip = StringStripWS($ip, 8)
        $t_ip = StringSplit($ip, ".")
        If $t_ip[0] = 4 AND StringIsDigit($t_ip[1]) AND StringIsDigit($t_ip[2]) AND StringIsDigit($t_ip[3]) AND StringIsDigit($t_ip[4]) Then
            Return $ip
        EndIf
    EndIf
    SetError(1)
    Return -1
EndFunc

Func _base64decode($data)
    Local $opcode = "0xC81000005356578365F800E8500000003EFFFFFF3F3435363738393A3B3C3DFFFFFF00FFFFFF000102030405060708090A0B0C0D0E0F10111213141516171819FFFFFFFFFFFF1A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132338F45F08B7D0C8B5D0831D2E9910000008365FC00837DFC047D548A034384C0750383EA033C3D75094A803B3D75014AB00084C0751A837DFC047D0D8B75FCC64435F400FF45FCEBED6A018F45F8EB1F3C2B72193C7A77150FB6F083EE2B0375F08A068B75FC884435F4FF45FCEBA68D75F4668B06C0E002C0EC0408E08807668B4601C0E004C0EC0208E08847018A4602C0E00624C00A46038847028D7F038D5203837DF8000F8465FFFFFF89D05F5E5BC9C21000"
    Local $codebuffer = DllStructCreate("byte[" & BinaryLen($opcode) & "]")
    DllStructSetData($codebuffer, 1, $opcode)
    Local $ouput = DllStructCreate("byte[" & BinaryLen($data) & "]")
    Local $ret = DllCall("user32.dll", "int", "CallWindowProc", "ptr", DllStructGetPtr($codebuffer), "str", $data, "ptr", DllStructGetPtr($ouput), "int", 0, "int", 0)
    Return BinaryMid(DllStructGetData($ouput, 1), 1, $ret[0])
EndFunc

Func _base64encode($data, $linebreak = 76)
    Local $opcode = "0x5589E5FF7514535657E8410000004142434445464748494A4B4C4D4E4F505152535455565758595A6162636465666768696A6B6C6D6E6F707172737475767778797A303132333435363738392B2F005A8B5D088B7D108B4D0CE98F0000000FB633C1EE0201D68A06880731C083F901760C0FB6430125F0000000C1E8040FB63383E603C1E60409C601D68A0688470183F90176210FB6430225C0000000C1E8060FB6730183E60FC1E60209C601D68A06884702EB04C647023D83F90276100FB6730283E63F01D68A06884703EB04C647033D8D5B038D7F0483E903836DFC04750C8B45148945FC66B80D0A66AB85C90F8F69FFFFFFC607005F5E5BC9C21000"
    Local $codebuffer = DllStructCreate("byte[" & BinaryLen($opcode) & "]")
    DllStructSetData($codebuffer, 1, $opcode)
    $data = Binary($data)
    Local $input = DllStructCreate("byte[" & BinaryLen($data) & "]")
    DllStructSetData($input, 1, $data)
    $linebreak = Floor($linebreak / 4) * 4
    Local $oputputsize = Ceiling(BinaryLen($data) * 4 / 3)
    $oputputsize = $oputputsize + Ceiling($oputputsize / $linebreak) * 2 + 4
    Local $ouput = DllStructCreate("char[" & $oputputsize & "]")
    DllCall("user32.dll", "none", "CallWindowProc", "ptr", DllStructGetPtr($codebuffer), "ptr", DllStructGetPtr($input), "int", BinaryLen($data), "ptr", DllStructGetPtr($ouput), "uint", $linebreak)
    Return DllStructGetData($ouput, 1)
EndFunc 

 
Usage Example:
P2Ptest.au3

Edited by nullschritt

Share this post


Link to post
Share on other sites



Reserved for previous versions.

Share this post


Link to post
Share on other sites

Hi this looks interesting.

Can you aid me a boost in the right direction?

Is lets say I develop a app for voting (poll) 

Do I setup my client as the destination and then give out my WAN and PORT to the peers and this way they build a list of peers?

Also I plan on using SQLite for the voting so I guess the peers need to build a voting list?

?

All nodes act as both a server and a client. You can easily build a simple server node though. The server node needs to simply be running on the same port as the node in your program. In your program enable bootstrapping. Whenever a new pc connects to this server, it will notify all connected clients of the new peer, and they will all try to connect.

You can always resolve a hostname to an ip address, and attempt to connect to it automatically with your code. You could also ask the user for an ip if that fails, or try a pre-generated list of other ip addresses.

If you want to make a pure peer-to-peer voting system, and want each node to store the votes in a sqlite file you will need to do two things.

1)Make a way to verify votes. This is to ensure a user doesnt send false votes into the network, or edit it into the file.

2)Make an update system for clients who have not been online. (Allow these clients to ask any other clients for any vote info they dont already have)

Share this post


Link to post
Share on other sites

Hi!

i have a problem :/

if i try to run P2PTest.au3, it throws me "Problem connection attempt: " and a number, every time i connect (press d)

if i turn on the debug on the UDF, it says: "P2P_: Connection failed: " and the same number.

The twitchyliquid64's udf works fine in my computer.

What can i do to fix the problem?

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

Hi!

i have a problem :/

if i try to run P2PTest.au3, it throws me "Problem connection attempt: " and a number, every time i connect (press d)

if i turn on the debug on the UDF, it says: "P2P_: Connection failed: " and the same number.

The twitchyliquid64's udf works fine in my computer.

What can i do to fix the problem?

It's probably because the bootstrapper has already connected you in this case.

Try pressing e to send some data. (with console out on)

Edited by nullschritt

Share this post


Link to post
Share on other sites

Just for the general public, I would put the bug you are having into the first post of this UDF -- >link

"I am having this same problem with the Event Driven P2P script based off this script, it's not sendign the data as packets, it's simply cutting off the string when it's send over a network connection, locally there is no limit for TCPSend, but it seems that over a network connection, only so many bytes can be transferred at once."

As I'm seeing people looking for the same thing, this could save someone a lot of time testing your code.. :)


Snips & Scripts


My Snips: graphCPUTemp ~ getENVvars
My Scripts: Short-Order Encrypter - message and file encryption V1.6.1 ~ AuPad - Notepad written entirely in AutoIt V1.9.4

Feel free to use any of my code for your own use.                                                                                                                                                           Forum FAQ

 

Share this post


Link to post
Share on other sites

Can you use _P2P_Connect($ip) to connect to some peers also? If so would you call it for each one or can you only call the _P2P_Connect($ip) function 1 time?

Thanks in advance for any informatin on this.

Share this post


Link to post
Share on other sites

Can you use _P2P_Connect($ip) to connect to some peers also? If so would you call it for each one or can you only call the _P2P_Connect($ip) function 1 time?

Thanks in advance for any informatin on this.

 

Every time you are trying to make a connection you call the connect function. But, please see the below quote as this could create errors; This whole library is based off a library that the author said not to use, just FYI :)>link

 

"I am having this same problem with the Event Driven P2P script based off this script, it's not sendign the data as packets, it's simply cutting off the string when it's send over a network connection, locally there is no limit for TCPSend, but it seems that over a network connection, only so many bytes can be transferred at once."


Snips & Scripts


My Snips: graphCPUTemp ~ getENVvars
My Scripts: Short-Order Encrypter - message and file encryption V1.6.1 ~ AuPad - Notepad written entirely in AutoIt V1.9.4

Feel free to use any of my code for your own use.                                                                                                                                                           Forum FAQ

 

Share this post


Link to post
Share on other sites

Thank you MikahS, for the information. Looks like I'll have to stick with what I had before looking at this...

Share this post


Link to post
Share on other sites

My pleasure ;)

What were you doing before?


Snips & Scripts


My Snips: graphCPUTemp ~ getENVvars
My Scripts: Short-Order Encrypter - message and file encryption V1.6.1 ~ AuPad - Notepad written entirely in AutoIt V1.9.4

Feel free to use any of my code for your own use.                                                                                                                                                           Forum FAQ

 

Share this post


Link to post
Share on other sites

Using two central servers. I'd like to learn about setting up p2p connections though.

Share this post


Link to post
Share on other sites

Have you had a look at Kealper's TCP server example by chance? >link

very nice way of doing a TCP server.


Snips & Scripts


My Snips: graphCPUTemp ~ getENVvars
My Scripts: Short-Order Encrypter - message and file encryption V1.6.1 ~ AuPad - Notepad written entirely in AutoIt V1.9.4

Feel free to use any of my code for your own use.                                                                                                                                                           Forum FAQ

 

Share this post


Link to post
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
Sign in to follow this  
Followers 0

  • Similar Content

    • tarretarretarre
      By tarretarretarre
      AutoIt-SocketIo
      Yep yep, this is pretty much an attempt to port the existing project's concept https://socket.io/ to AutoIt's Codebase. So i will not go in to so much detail.
      This is how the communication is done http://i.imgur.com/0mMfsBD.png Each client is isolated to the server http://i.imgur.com/rVO2LFb.png Features
      Easy API VarType Translation (Example: If the server sends an int, the client will receive an int and vice versa) Fully featured examples Data encryption (Using Autoit's UDF Crypt.au3) Limitations / Drawbacks
      Every Broadcast/Emit is limited to a maximum of 16 parameters Every Callback Function has to have the same number of parameters as the Broadcasted/Emited event It is not possible to Broadcast/Emit objects Only 1D-arrays are allowed to be Broadcasted/Emitted (2D arrays will probably never be supported) Changelog
      Version 1.4.0 (This update DOES NOT break scripts)
      Added a new server method: _Io_getSockets which will return an array of all sockets. See more in the doc Added a banning-system, see more at: _Io_getBanlist, _Io_Ban, _Io_Sanction, _Io_IsBanned Added a new default event for clients banned. See more at default events Added two new client and server methods _Io_setEventPreScript And _Io_setEventPostScript. The intent for these is to not DRY when doing debug \ tasks that requires to be ran before or after events. Added a new client and server method _Io_ClearEvents. Added a third optional parameter to _Io_On called $socket, you may only pass the socket returned from _Io_Listen or _Io_Connect. The intent for this change is to allow for server + client in the same envoirment. Added a second parameter to _Io_Loop called $WhoAmI which should used with the new enums $_IO_SERVER and $_IO_CLIENT. The intent for this change is to allow for server + client in the same envoirment. Added a new client method _Io_TransferSocket. Added a new server method _Io_getActiveSocketCount. Optimations, avoiding Redims and unnecessary nested arrays as good as possible etc. Version 1.3.0 (This update DOES NOT break scripts)
      Got rid of unnecessary Redims with sockets and subscriptions in the main loop (This increased write performence greatly) Changed $iMaxDeadSocketsBeforeTidy from 100 to 1000 Changed _Io_setRecvPackageSize($nPackageSize = 2048) to _Io_setRecvPackageSize($nPackageSize = 4096) because 2017. Added Tests for both subscriptions and the automatic TidyUp Added a new server method: _Io_getMaxConnections Added a new server method: _Io_getMaxDeadSocketsCount Added a fifth parameter to the _Io_Listen method called $iMaxConnections which defaults to 100000. If the iMaxConnection + 1 user connects, they will be instantly disconnected. Added a parameter to _Io_Disconnect called $socket which defaults to null. If the iMaxConnections + 1 client connects, they will be instantly disconnected. Version 1.2.0 (This update DOES NOT break scripts)
      Added an option to set the packet-size of TCP-transports, see _Io_setRecvPackageSize Got rid of unnecessary StringLen's in _Io_loop Changed __Io_TidyUp to _Io_TidyUp and added it to the public Api reference list. Changed $iMaxDeadSocketsBeforeTidy default value from 1000 to 100 and added an option to disable it, read more at _Io_Listen Changed $bAutoReconnect from False to True. Fixed gitignore epicZ fail Improvemend Documentation Version 1.1.0 (This update DOES NOT break scripts)
      Fixed bug when Emitting / Broadcasting without any parameters causing a $fCallback crash Optimized Package-handling once again. Added 1D-Array support (Endless nestning). Added Subscriptions (See _Io_Subscribe _Io_Unsubscribe and _Io_BroadcastToRoom). Added new example for subscriptions (Be sure to use different room names when joining with clients) Added Unit testing (See Tests\Runner.au3 and Tests\Tests.au3, to run tests you need a udf found here: https://github.com/tarreislam/Autoit-Unit-Tester) Version 1.0.0
      (This update DOES NOT break scripts) Added data encryption (Using Autoit's UDF Crypt.au3) See more at _Io_EnableEncryption Added new method _Io_Disconnect which can be used with both servers and clients Improved package-handling to increase performance Increased the limit of Broadcasted/Emit parameters from 10 to 16 Api methods
      Server methods
      _Io_Listen($iPort, $iAddress = @IPAddress1, $iMaxPendingConnections = Default, $iMaxDeadSocketsBeforeTidy = 1000, $iMaxConnections = 100000) _Io_Subscribe(ByRef $socket, $sRoomName) _Io_Unsubscribe(ByRef $socket, $sRoomName = null) _Io_Broadcast(ByRef $socket, $sEventName, $p1, $p2, ...$p16)  
      _Io_BroadcastToAll(ByRef $socket, $sEventName, $p1, $p2, ...$p16) _Io_BroadcastToRoom(ByRef $socket, $sDesiredRoomName, $sEventName, $p1, $p2, ...$p16) _Io_socketGetProperty(ByRef $socket, $sProp = Default) _Io_getSockets($bForceUpdate = False, $socket = $__g_io_mySocket, $whoAmI = $__g_io_whoami) _Io_getDeadSocketCount() _Io_getSocketsCount() _Io_getActiveSocketCount() _Io_getMaxConnections() _Io_getMaxDeadSocketsCount() _Io_getBanlist($iEntry = Default) _Io_Ban($socketOrIp, $nTime = 3600, $sReason = "Banned", $sIssuedBy = "system") _Io_Sanction($socketOrIp) _Io_IsBanned($socketOrIp) _Io_TidyUp() Client methods
      _Io_Connect($iAddress, $iPort, $bAutoReconnect = True) _Io_Reconnect(ByRef $socket) Server and Client methods
      _Io_setEventPreScript($fCallback) _Io_setEventPostScript($fCallback) _Io_getVer() _Io_On(Const $sEventName, Const $fCallback, $socket = $__g_io_mySocket) _Io_Emit(ByRef $socket, $sEventName, $p1, $p2, ...$p16) _Io_Loop(ByRef $socket, $whoAmI = $__g_io_whoami) _Io_LoopFacade() _Io_EnableEncryption($sFileOrKey, $CryptAlgId = $CALG_AES_256) _Io_Disconnect($socket = null) _Io_setRecvPackageSize($nPackageSize = 4096) _Io_ClearEvents() _Io_TransferSocket(ByRef $from, ByRef $to) Default events
      Server events
      connection Client events
      banned Server and Client events
      disconnect View source on github
       
      Autoit-Socket-IO-1.0.0.zip (OLD!)
      Autoit-Socket-IO-1.1.0.zip (OLD)
      Autoit-Socket-IO-1.3.0.zip (OLD)
      Autoit-Socket-IO-1.4.0.zip (NEWEST 2017-08-11)
    • timmalos
      By timmalos
      Hello all.
      In case this is interesting few of you, I share my AMCP 2.1 protocol UDF in AutoIT. This protocol is used by CasparCG server, which is a Windows and Linux software used to play out professional graphics, audio and video to multiple outputs as a layerbased real-time compositor. It has been in 24/7 broadcast production since 2006. It's free and opensource.
      The UDF I share allows communication between an AutoIt based client and the CasparCG, based on following documentation : http://casparcg.com/wiki/CasparCG_2.1_AMCP_Protocol
      If you want more details on CasparCG :  official WebSite or have a look to this video
      I'm currently building a full Client based on AutoIt, with many features like drag-and-drop layers, but sadly I can't share it right now, might come later. Don't hesitate to ask questions if you have any or need a basic example.
      The only requirement for this UDF is the other Event-driven TCP UDF by Kip
       
       

      AMCP_shared.au3
      TCP.au3
    • kingjacob90
      By kingjacob90
      Hi
      I am trying to send a file over TCP from a TCP client to server. If I run the server and client on the same computer the file is send fine, but if the server is on one computer on the network and the client on another the file is sent in what looks like more than one packet. In other words the server receives 4 msg from the client.
      Why is this, how do I make it send in one go, or what is a way around it?
      Side Note: TCP server has a max of 999999999
    • AlexFing17
      By AlexFing17
      i am trying to figure out how a server can connect to a client Over the internet. 
      In this is script. The client connects to the server on the same machine (localhost) and executes the commands from the client.
      How can I change that instead communicating over localhost to communicate over the internet with tcp ipaddress and a port.
       
      What i actually need help of is
      1. The server will open a port and  listen to communication from a No-ip address
      2. I input the no-ip address and correct port in the client side, and when i click on connect, it connects to the server if its online
       
       
      This is the client
      #include <GuiConstantsEx.au3> THIS IS THE CLIENT #include <NamedPipes.au3> #include <StaticConstants.au3> #include <WinAPI.au3> #include <WindowsConstants.au3> ; =============================================================================================================================== ; Description ...: This is the client side of the pipe demo ; Author ........: Paul Campbell (PaulIA) ; Notes .........: ; =============================================================================================================================== ; =============================================================================================================================== ; Global constants ; =============================================================================================================================== Global Const $BUFSIZE = 4096 Global Const $DEFCMD = "cmd.exe /c dir c:\" Global Const $PIPE_NAME = "\\$\\pipe\\AutoIt3" Global Const $ERROR_MORE_DATA = 234 ; =============================================================================================================================== ; Global variables ; =============================================================================================================================== Global $g_idEdit, $g_idMemo, $g_idSend, $g_idServer, $g_hPipe ; =============================================================================================================================== ; Main ; =============================================================================================================================== CreateGUI() MsgLoop() ; =============================================================================================================================== ; Creates a GUI for the client ; =============================================================================================================================== Func CreateGUI() Local $hGUI = GUICreate("FarC0nn3c7", 500, 400, -1, -1, $WS_SIZEBOX) GUICtrlCreateLabel("Server:", 2, 14, 52, 20, $SS_RIGHT) $g_idServer = GUICtrlCreateEdit("<local>", 56, 10, 200, 20, $SS_LEFT) GUICtrlCreateLabel("Command:", 2, 36, 52, 20, $SS_RIGHT) $g_idEdit = GUICtrlCreateEdit($DEFCMD, 56, 32, 370, 20, $SS_LEFT) $g_idSend = GUICtrlCreateButton("Pawn Dem", 430, 32, 60, 20) $g_idMemo = GUICtrlCreateEdit("", 0, 62, _WinAPI_GetClientWidth($hGUI), 332) GUICtrlSetFont($g_idMemo, 9, 400, 0, "Courier New") GUISetState() EndFunc ;==>CreateGUI ; =============================================================================================================================== ; Logs an error message to the display ; =============================================================================================================================== Func LogError($sMessage) $sMessage &= " (" & _WinAPI_GetLastErrorMessage() & ")" GUICtrlSetData($g_idMemo, GUICtrlRead($g_idMemo) & $sMessage & @CRLF) EndFunc ;==>LogError ; =============================================================================================================================== ; Logs a message to the display ; =============================================================================================================================== Func LogMsg($sMessage) GUICtrlSetData($g_idMemo, GUICtrlRead($g_idMemo) & $sMessage & @CRLF) EndFunc ;==>LogMsg ; =============================================================================================================================== ; MsgLoop ; =============================================================================================================================== Func MsgLoop() While True Switch GUIGetMsg() Case $g_idSend SendCmd() Case $GUI_EVENT_CLOSE Exit EndSwitch WEnd EndFunc ;==>MsgLoop ; =============================================================================================================================== ; This function opens a pipe to the server ; =============================================================================================================================== Func OpenPipe() Local $sName, $sPipe ; Get pipe handle $sName = GUICtrlRead($g_idServer) If $sName = "<local>" Then $sName = "." $sPipe = StringReplace($PIPE_NAME, "$", $sName) $g_hPipe = _WinAPI_CreateFile($sPipe, 2, 6) If $g_hPipe <> -1 Then Return True LogError("OpenPipe failed") Return False EndFunc ;==>OpenPipe ; =============================================================================================================================== ; This function reads a message from the pipe ; =============================================================================================================================== Func ReadMsg() Local $bSuccess, $iRead, $pBuffer, $tBuffer $tBuffer = DllStructCreate("char Text[4096]") $pBuffer = DllStructGetPtr($tBuffer) GUICtrlSetData($g_idMemo, "") While 1 $bSuccess = _WinAPI_ReadFile($g_hPipe, $pBuffer, $BUFSIZE, $iRead, 0) If $iRead = 0 Then ExitLoop If Not $bSuccess Or (_WinAPI_GetLastError() = $ERROR_MORE_DATA) Then ExitLoop GUICtrlSetData($g_idMemo, StringLeft(DllStructGetData($tBuffer, "Text"), $iRead), 1) WEnd EndFunc ;==>ReadMsg ; =============================================================================================================================== ; This function sends a command to the server ; =============================================================================================================================== Func SendCmd() If OpenPipe() Then SetReadMode() WriteMsg(GUICtrlRead($g_idEdit)) ReadMsg() _WinAPI_CloseHandle($g_hPipe) EndIf EndFunc ;==>SendCmd ; =============================================================================================================================== ; This function sets the pipe read mode ; =============================================================================================================================== Func SetReadMode() If Not _NamedPipes_SetNamedPipeHandleState($g_hPipe, 1, 0, 0, 0) Then LogError("SetReadMode: _NamedPipes_SetNamedPipeHandleState failed") EndIf EndFunc ;==>SetReadMode ; =============================================================================================================================== ; This function writes a message to the pipe ; =============================================================================================================================== Func WriteMsg($sMessage) Local $iWritten, $iBuffer, $pBuffer, $tBuffer $iBuffer = StringLen($sMessage) + 1 $tBuffer = DllStructCreate("char Text[" & $iBuffer & "]") $pBuffer = DllStructGetPtr($tBuffer) DllStructSetData($tBuffer, "Text", $sMessage) If Not _WinAPI_WriteFile($g_hPipe, $pBuffer, $iBuffer, $iWritten, 0) Then LogError("WriteMsg: _WinAPI_WriteFile failed") EndIf EndFunc ;==>WriteMsg  
      And this is the server
      #include <GuiConstantsEx.au3> #include <NamedPipes.au3> #include <WinAPI.au3> #include <WindowsConstants.au3> #NoTrayIcon ; =============================================================================================================================== ; Description ...: This is the server side of the pipe demo ; Author ........: Paul Campbell (PaulIA) ; Notes .........: ; =============================================================================================================================== ; =============================================================================================================================== ; Global constants ; =============================================================================================================================== Global Const $DEBUGGING = False Global Const $BUFSIZE = 4096 Global Const $PIPE_NAME = "\\.\\pipe\\AutoIt3" Global Const $TIMEOUT = 5000 Global Const $WAIT_TIMEOUT = 258 Global Const $ERROR_IO_PENDING = 997 Global Const $ERROR_PIPE_CONNECTED = 535 ; =============================================================================================================================== ; Global variables ; =============================================================================================================================== Global $g_hEvent, $g_idMemo, $g_pOverlap, $g_tOverlap, $g_hPipe, $g_hReadPipe, $g_iState, $g_iToWrite ; =============================================================================================================================== ; Main ; =============================================================================================================================== CreateGUI() InitPipe() MsgLoop() ; =============================================================================================================================== ; Creates a GUI for the server ; =============================================================================================================================== Func CreateGUI() Local $hGUI $hGUI = GUICreate("Pipe Server", 500, 400, -1, -1, $WS_SIZEBOX) $g_idMemo = GUICtrlCreateEdit("", 0, 0, _WinAPI_GetClientWidth($hGUI), _WinAPI_GetClientHeight($hGUI)) GUICtrlSetFont($g_idMemo, 9, 400, 0, "Courier New") GUISetState() EndFunc ;==>CreateGUI ; =============================================================================================================================== ; This function creates an instance of a named pipe ; =============================================================================================================================== Func InitPipe() ; Create an event object for the instance $g_tOverlap = DllStructCreate($tagOVERLAPPED) $g_pOverlap = DllStructGetPtr($g_tOverlap) $g_hEvent = _WinAPI_CreateEvent() If $g_hEvent = 0 Then LogError("InitPipe ..........: API_CreateEvent failed") Return EndIf DllStructSetData($g_tOverlap, "hEvent", $g_hEvent) ; Create a named pipe $g_hPipe = _NamedPipes_CreateNamedPipe($PIPE_NAME, _ ; Pipe name 2, _ ; The pipe is bi-directional 2, _ ; Overlapped mode is enabled 0, _ ; No security ACL flags 1, _ ; Data is written to the pipe as a stream of messages 1, _ ; Data is read from the pipe as a stream of messages 0, _ ; Blocking mode is enabled 1, _ ; Maximum number of instances $BUFSIZE, _ ; Output buffer size $BUFSIZE, _ ; Input buffer size $TIMEOUT, _ ; Client time out 0) ; Default security attributes If $g_hPipe = -1 Then LogError("InitPipe ..........: _NamedPipes_CreateNamedPipe failed") Else ; Connect pipe instance to client ConnectClient() EndIf EndFunc ;==>InitPipe ; =============================================================================================================================== ; This function loops waiting for a connection event or the GUI to close ; =============================================================================================================================== Func MsgLoop() Local $iEvent Do $iEvent = _WinAPI_WaitForSingleObject($g_hEvent, 0) If $iEvent < 0 Then LogError("MsgLoop ...........: _WinAPI_WaitForSingleObject failed") Exit EndIf If $iEvent = $WAIT_TIMEOUT Then ContinueLoop Debug("MsgLoop ...........: Instance signaled") Switch $g_iState Case 0 CheckConnect() Case 1 ReadRequest() Case 2 CheckPending() Case 3 RelayOutput() EndSwitch Until GUIGetMsg() = $GUI_EVENT_CLOSE EndFunc ;==>MsgLoop ; =============================================================================================================================== ; Checks to see if the pending client connection has finished ; =============================================================================================================================== Func CheckConnect() Local $iBytes ; Was the operation successful? If Not _WinAPI_GetOverlappedResult($g_hPipe, $g_pOverlap, $iBytes, False) Then LogError("CheckConnect ......: Connection failed") ReconnectClient() Else $g_iState = 1 EndIf EndFunc ;==>CheckConnect ; =============================================================================================================================== ; This function reads a request message from the client ; =============================================================================================================================== Func ReadRequest() Local $pBuffer, $tBuffer, $iRead, $bSuccess $tBuffer = DllStructCreate("char Text[" & $BUFSIZE & "]") $pBuffer = DllStructGetPtr($tBuffer) $bSuccess = _WinAPI_ReadFile($g_hPipe, $pBuffer, $BUFSIZE, $iRead, $g_pOverlap) If $bSuccess And ($iRead <> 0) Then ; The read operation completed successfully Debug("ReadRequest .......: Read success") Else ; Wait for read Buffer to complete If Not _WinAPI_GetOverlappedResult($g_hPipe, $g_pOverlap, $iRead, True) Then LogError("ReadRequest .......: _WinAPI_GetOverlappedResult failed") ReconnectClient() Return Else ; Read the command from the pipe $bSuccess = _WinAPI_ReadFile($g_hPipe, $pBuffer, $BUFSIZE, $iRead, $g_pOverlap) If Not $bSuccess Or ($iRead = 0) Then LogError("ReadRequest .......: _WinAPI_ReadFile failed") ReconnectClient() Return EndIf EndIf EndIf ; Execute the console command If Not ExecuteCmd(DllStructGetData($tBuffer, "Text")) Then ReconnectClient() Return EndIf ; Relay console output back to the client $g_iState = 3 EndFunc ;==>ReadRequest ; =============================================================================================================================== ; This function relays the console output back to the client ; =============================================================================================================================== Func CheckPending() Local $bSuccess, $iWritten $bSuccess = _WinAPI_GetOverlappedResult($g_hPipe, $g_pOverlap, $iWritten, False) If Not $bSuccess Or ($iWritten <> $g_iToWrite) Then Debug("CheckPending ......: Write reconnecting") ReconnectClient() Else Debug("CheckPending ......: Write complete") $g_iState = 3 EndIf EndFunc ;==>CheckPending ; =============================================================================================================================== ; This function relays the console output back to the client ; =============================================================================================================================== Func RelayOutput() Local $pBuffer, $tBuffer, $sLine, $iRead, $bSuccess, $iWritten $tBuffer = DllStructCreate("char Text[" & $BUFSIZE & "]") $pBuffer = DllStructGetPtr($tBuffer) ; Read data from console pipe _WinAPI_ReadFile($g_hReadPipe, $pBuffer, $BUFSIZE, $iRead) If $iRead = 0 Then LogMsg("RelayOutput .......: Write done") _WinAPI_CloseHandle($g_hReadPipe) _WinAPI_FlushFileBuffers($g_hPipe) ReconnectClient() Return EndIf ; Get the data and strip out the extra carriage returns $sLine = StringLeft(DllStructGetData($tBuffer, "Text"), $iRead) $sLine = StringReplace($sLine, @CR & @CR, @CR) $g_iToWrite = StringLen($sLine) DllStructSetData($tBuffer, "Text", $sLine) ; Relay the data back to the client $bSuccess = _WinAPI_WriteFile($g_hPipe, $pBuffer, $g_iToWrite, $iWritten, $g_pOverlap) If $bSuccess And ($iWritten = $g_iToWrite) Then Debug("RelayOutput .......: Write success") Else If Not $bSuccess And (_WinAPI_GetLastError() = $ERROR_IO_PENDING) Then Debug("RelayOutput .......: Write pending") $g_iState = 2 Else ; An error occurred, disconnect from the client LogError("RelayOutput .......: Write failed") ReconnectClient() EndIf EndIf EndFunc ;==>RelayOutput ; =============================================================================================================================== ; This function is called to start an overlapped connection operation ; =============================================================================================================================== Func ConnectClient() $g_iState = 0 ; Start an overlapped connection If _NamedPipes_ConnectNamedPipe($g_hPipe, $g_pOverlap) Then LogError("ConnectClient .....: ConnectNamedPipe 1 failed") Else Switch @error ; The overlapped connection is in progress Case $ERROR_IO_PENDING Debug("ConnectClient .....: Pending") ; Client is already connected, so signal an event Case $ERROR_PIPE_CONNECTED LogMsg("ConnectClient .....: Connected") $g_iState = 1 If Not _WinAPI_SetEvent(DllStructGetData($g_tOverlap, "hEvent")) Then LogError("ConnectClient .....: SetEvent failed") EndIf ; Error occurred during the connection event Case Else LogError("ConnectClient .....: ConnectNamedPipe 2 failed") EndSwitch EndIf EndFunc ;==>ConnectClient ; =============================================================================================================================== ; Dumps debug information to the screen ; =============================================================================================================================== Func Debug($sMessage) If $DEBUGGING Then LogMsg($sMessage) EndFunc ;==>Debug ; =============================================================================================================================== ; Executes a command and returns the results ; =============================================================================================================================== Func ExecuteCmd($sCmd) Local $tProcess, $tSecurity, $tStartup, $hWritePipe ; Set up security attributes $tSecurity = DllStructCreate($tagSECURITY_ATTRIBUTES) DllStructSetData($tSecurity, "Length", DllStructGetSize($tSecurity)) DllStructSetData($tSecurity, "InheritHandle", True) ; Create a pipe for the child process's STDOUT If Not _NamedPipes_CreatePipe($g_hReadPipe, $hWritePipe, $tSecurity) Then LogError("ExecuteCmd ........: _NamedPipes_CreatePipe failed") Return False EndIf ; Create child process $tProcess = DllStructCreate($tagPROCESS_INFORMATION) $tStartup = DllStructCreate($tagSTARTUPINFO) DllStructSetData($tStartup, "Size", DllStructGetSize($tStartup)) DllStructSetData($tStartup, "Flags", BitOR($STARTF_USESTDHANDLES, $STARTF_USESHOWWINDOW)) DllStructSetData($tStartup, "StdOutput", $hWritePipe) DllStructSetData($tStartup, "StdError", $hWritePipe) If Not _WinAPI_CreateProcess("", $sCmd, 0, 0, True, 0, 0, "", DllStructGetPtr($tStartup), DllStructGetPtr($tProcess)) Then LogError("ExecuteCmd ........: _WinAPI_CreateProcess failed") _WinAPI_CloseHandle($g_hReadPipe) _WinAPI_CloseHandle($hWritePipe) Return False EndIf _WinAPI_CloseHandle(DllStructGetData($tProcess, "hProcess")) _WinAPI_CloseHandle(DllStructGetData($tProcess, "hThread")) ; Close the write end of the pipe so that we can read from the read end _WinAPI_CloseHandle($hWritePipe) LogMsg("ExecuteCommand ....: " & $sCmd) Return True EndFunc ;==>ExecuteCmd ; =============================================================================================================================== ; Logs an error message to the display ; =============================================================================================================================== Func LogError($sMessage) $sMessage &= " (" & _WinAPI_GetLastErrorMessage() & ")" ConsoleWrite($sMessage & @LF) EndFunc ;==>LogError ; =============================================================================================================================== ; This function is called when an error occurs or when the client closes its handle to the pipe ; =============================================================================================================================== Func ReconnectClient() ; Disconnect the pipe instance If Not _NamedPipes_DisconnectNamedPipe($g_hPipe) Then LogError("ReconnectClient ...: DisonnectNamedPipe failed") Return EndIf ; Connect to a new client ConnectClient() EndFunc ;==>ReconnectClient  
    • VIP
      By VIP
      Use: 
       
      Server Script:
      #include <ButtonConstants.au3> #include <EditConstants.au3> #include <GUIConstantsEx.au3> #include <StaticConstants.au3> #include <WindowsConstants.au3> #include <GUIConstantsEx.au3> #include <GuiEdit.au3> #include <GuiStatusBar.au3> #include <MsgBoxConstants.au3> #include <ScrollBarsConstants.au3> #include <WindowsConstants.au3> #include "TCP.au3" OnAutoItExitRegister("_OnExit") Func _OnExit() TCPShutdown() Exit EndFunc ;==>_OnExit #Region Global $hGUI = GUICreate("TCP AutoIT Server", 620, 400, -1, -1, -1, BitOR($WS_EX_ACCEPTFILES, $WS_EX_TOPMOST, $WS_EX_WINDOWEDGE)) Global $sMode = GUICtrlCreateRadio("Server Mode", 16, 8, 97, 17) GUICtrlSetState(-1, $GUI_CHECKED) Global $sGlobalIP = GUICtrlCreateInput("", 170, 8, 120, 21, $ES_READONLY) Global $sServerIP = GUICtrlCreateInput(@IPAddress1, 300, 8, 120, 21, $ES_READONLY) Global $sServerPORT = GUICtrlCreateInput("8888", 425, 8, 39, 21) GUICtrlCreateLabel("IP Server:", 120, 10, 51, 17) Global $bStartServer = GUICtrlCreateButton("Start Server", 512, 6, 89, 33) Global $gMessenger = GUICtrlCreateGroup("Text to Send", 8, 64, 601, 129) Global $tMessenger = GUICtrlCreateEdit("", 15, 85, 489, 97, BitOR($ES_AUTOVSCROLL, $ES_WANTRETURN, $WS_VSCROLL)) GUICtrlSetData(-1, "[START]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[END]") Global $bSendMes = GUICtrlCreateButton("SEND", 511, 83, 89, 105) GUICtrlCreateGroup("", -99, -99, 1, 1) GUICtrlCreateLabel("File To Send:", 16, 200, 80, 17) Global $sPathFileSend = GUICtrlCreateInput(@TempDir & "\XXX.jpg", 104, 200, 361, 21) Global $bSelectFile = GUICtrlCreateButton(".!.", 472, 200, 35, 25) GUICtrlCreateLabel("Path To Save:", 16, 230, 80, 17) Global $sPathFileSave = GUICtrlCreateInput(@DesktopDir, 104, 230, 361, 21) Global $bSelectDir = GUICtrlCreateButton("...", 472, 230, 35, 25) Global $bSendFile = GUICtrlCreateButton("Send File", 512, 195, 89, 60) ;~ Global $tStatus = GUICtrlCreateLabel("", 16, 45, 580, 17) Global $tStatus = GUICtrlCreateLabel("List Client:", 36, 45, 60, 17) Global $listClient = GUICtrlCreateCombo("", 100, 45, 500, 17) Global $gReceived = GUICtrlCreateGroup("Received", 8, 266, 601, 129) Global $cDataReceived = GUICtrlCreateEdit("", 16, 282, 585, 105, BitOR($ES_AUTOVSCROLL, $ES_WANTRETURN, $WS_VSCROLL)) GUICtrlSetData(-1, "") GUICtrlCreateGroup("", -99, -99, 1, 1) GUISetState(@SW_SHOW) #EndRegion Global $hClient, $xSocket, $xServerIP, $xServerPORT, $xPathFileSend, $xPathFileSave, $xGlobalIP = GetIP() GUICtrlSetData($sGlobalIP, $xGlobalIP) _WriteLog("Server IP WAN: " & $xGlobalIP) While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE Exit Case $bStartServer _WriteLog("SERVER: Starting up server...") $xServerIP = GUICtrlRead($sServerIP) $xServerPORT = GUICtrlRead($sServerPORT) _WriteLog("Server IP: " & $xServerIP) _WriteLog("Server Port: " & $xServerPORT) $hServer = _TCP_Server_Create($xServerPORT, "0.0.0.0") _TCP_RegisterEvent($hServer, $TCP_NEWCLIENT, "NewClient") _TCP_RegisterEvent($hServer, $TCP_DISCONNECT, "Disconnect") _TCP_RegisterEvent($hServer, $TCP_RECEIVE, "Recieved") _WriteLog( "SERVER: Started") GUICtrlSetData($bStartServer, "Running") GUICtrlSetState($bStartServer, $GUI_DISABLE) Case $bSendFile ConsoleWrite("Send File Pressed!" & @CRLF) Case $bSendMes Local $sClient = GUICtrlRead($listClient) $xMessenger = GUICtrlRead($tMessenger) _TCP_Send($sClient, $xMessenger) ConsoleWrite("Send Messenger Pressed!" & @CRLF) Case $bSelectFile $xPathFileSend = FileOpenDialog("Select file to send:", @DesktopDir, "All (*.*)", 3, "", $hGUI) If Not @error Then GUICtrlSetData($sPathFileSend, $xPathFileSend) Case $bSelectDir $xPathFileSave = FileSelectFolder("Select local to save file received:", @DesktopDir, 0, @ScriptDir, $hGUI) If Not @error Then GUICtrlSetData($sPathFileSave, $xPathFileSave) EndSwitch Sleep(1) WEnd Func NewClient($hSocket, $iError) GUICtrlSetData($listClient, $hSocket, $hSocket) _WriteLog("SERVER: New client connected/ Socket:" & $hSocket & " /Sending this: Welcome!") _TCP_Send($hSocket, "Welcome!") EndFunc ;==>NewClient Func Received($hSocket, $sReceived, $iError) _WriteLog("CLIENT: We received from Socket: " & $hSocket & " data: " & $sReceived) EndFunc ;==>Received Func Disconnect($hSocket, $iError) _WriteLog("SERVER: Client disconnected. Socket:" & $hSocket) EndFunc ;==>Disconnect Func _WriteLog($sLogMsg) Local $OldLog = GUICtrlRead($cDataReceived) GUICtrlSetData($cDataReceived, $OldLog & @CRLF & $sLogMsg) ;~ GUICtrlSetData($tStatus, $sLogMsg) ConsoleWrite("! " & $sLogMsg & @CRLF) $iEnd = StringLen(GUICtrlRead($tMessenger)) _GUICtrlEdit_SetSel($tMessenger, $iEnd, $iEnd) _GUICtrlEdit_Scroll($tMessenger, $SB_SCROLLCARET) $iEnd = StringLen(GUICtrlRead($cDataReceived)) _GUICtrlEdit_SetSel($cDataReceived, $iEnd, $iEnd) _GUICtrlEdit_Scroll($cDataReceived, $SB_SCROLLCARET) EndFunc ;==>_WriteLog Func GetIP($i = "ip") Local $return, $IP = StringSplit(BinaryToString(InetRead("http://api.wipmania.com/")), "<br>", 1) If $i = "from" Then If Not $IP[1] = "" Then $return = $IP[2] Else Return "Error: Api not responding." EndIf Else If Not $IP[1] = "" Then $return = $IP[1] Else Return "Error: Api not responding." EndIf EndIf Return $return EndFunc ;==>GetIP Client Script:
      #include <ButtonConstants.au3> #include <EditConstants.au3> #include <GUIConstantsEx.au3> #include <StaticConstants.au3> #include <WindowsConstants.au3> #include <GUIConstantsEx.au3> #include <GuiEdit.au3> #include <GuiStatusBar.au3> #include <MsgBoxConstants.au3> #include <ScrollBarsConstants.au3> #include <WindowsConstants.au3> #include "TCP.au3" OnAutoItExitRegister("_OnExit") Func _OnExit() TCPShutdown() Exit EndFunc ;==>_OnExit #Region Global $hGUI = GUICreate("TCP AutoIT Client", 620, 400, -1, -1, -1, BitOR($WS_EX_ACCEPTFILES, $WS_EX_TOPMOST, $WS_EX_WINDOWEDGE)) Global $sMode = GUICtrlCreateRadio("Client Mode", 16, 8, 97, 17) GUICtrlSetState(-1, $GUI_CHECKED) Global $sConnectStatus = GUICtrlCreateLabel("", 408, 8, 89, 17) Global $sServerIP = GUICtrlCreateInput(@IPAddress1, 224, 8, 120, 21) Global $sServerPORT = GUICtrlCreateInput("8888", 345, 8, 39, 21) GUICtrlCreateLabel("IP Server:", 160, 10, 51, 17) Global $bStartConnect = GUICtrlCreateButton("Start Connect", 512, 6, 89, 33) Global $gMessenger = GUICtrlCreateGroup("Text to Send", 8, 64, 601, 129) Global $tMessenger = GUICtrlCreateEdit("", 15, 85, 489, 97, BitOR($ES_AUTOVSCROLL, $ES_WANTRETURN, $WS_VSCROLL)) GUICtrlSetData(-1, "[START]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[END]") Global $bSendMes = GUICtrlCreateButton("SEND", 511, 83, 89, 105) GUICtrlCreateGroup("", -99, -99, 1, 1) GUICtrlCreateLabel("File To Send:", 16, 200, 80, 17) Global $sPathFileSend = GUICtrlCreateInput(@TempDir & "\XXX.jpg", 104, 200, 361, 21) Global $bSelectFile = GUICtrlCreateButton(".!.", 472, 200, 35, 25) GUICtrlCreateLabel("Path To Save:", 16, 230, 80, 17) Global $sPathFileSave = GUICtrlCreateInput(@DesktopDir, 104, 230, 361, 21) Global $bSelectDir = GUICtrlCreateButton("...", 472, 230, 35, 25) Global $bSendFile = GUICtrlCreateButton("Send File", 512, 195, 89, 60) ;~ Global $tStatus = GUICtrlCreateLabel("", 16, 45, 580, 17) Global $gReceived = GUICtrlCreateGroup("Received", 8, 266, 601, 129) Global $cDataReceived = GUICtrlCreateEdit("", 16, 282, 585, 105, BitOR($ES_AUTOVSCROLL, $ES_WANTRETURN, $WS_VSCROLL)) GUICtrlSetData(-1, "") GUICtrlCreateGroup("", -99, -99, 1, 1) GUISetState(@SW_SHOW) #EndRegion Global $hClient, $xSocket, $xServerIP, $xServerPORT, $xPathFileSend, $xPathFileSave While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE Exit Case $bStartConnect $xServerIP = GUICtrlRead($sServerIP) $xServerPORT = GUICtrlRead($sServerPORT) _WriteLog("Server Port: " & $xServerIP) _WriteLog("Server Port: " & $xServerPORT) $hClient = _TCP_Client_Create($xServerIP, $xServerPORT) ; Create the client. Which will connect to the local ip address on port xxxx _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. _WriteLog("CLIENT: Connecting...") Case $bSendFile ConsoleWrite("Send File Pressed!" & @CRLF) ;~ Exit Case $bSendMes $xMessenger = GUICtrlRead($tMessenger) _TCP_Send($xSocket, $xMessenger) ConsoleWrite("Send Messenger Pressed!" & @CRLF) Case $bSelectFile $xPathFileSend = FileOpenDialog("Select file to send:", @DesktopDir, "All (*.*)", 3, "", $hGUI) If Not @error Then GUICtrlSetData($sPathFileSend, $xPathFileSend) Case $bSelectDir $xPathFileSave = FileSelectFolder("Select local to save file received:", @DesktopDir, 0, @ScriptDir, $hGUI) If Not @error Then GUICtrlSetData($sPathFileSave, $xPathFileSave) EndSwitch Sleep(1) WEnd Func Connected($hSocket, $iError) If Not $iError Then _WriteLog("CLIENT: Connected!") GUICtrlSetData($bStartConnect, "Conneced") GUICtrlSetState($bStartConnect, $GUI_DISABLE) _WriteLog( "CLIENT: Conneced") ;~ _TCP_Send($hSocket, "Conneced :)") ;~ $xMessenger = GUICtrlRead($tMessenger) ;~ _TCP_Send($hSocket, $xMessenger) ;~ _WriteLog("CLIENT: Try reply socket: " & $hSocket & " data: " & $xMessenger) Else _WriteLog("CLIENT: Could not connect. Are you sure the server is running?") EndIf EndFunc ;==>Connected Func Received($hSocket, $sReceived, $iError) _WriteLog("CLIENT: We received from socket: " & $hSocket & " data: " & $sReceived) Sleep(1000) EndFunc ;==>Received Func Disconnect($hSocket, $iError) _WriteLog("SERVER: Client disconnected. Socket:" & $hSocket) EndFunc ;==>Disconnect Func _WriteLog($sLogMsg) Local $OldLog = GUICtrlRead($cDataReceived) GUICtrlSetData($cDataReceived, $OldLog & @CRLF & $sLogMsg) ;~ GUICtrlSetData($tStatus, $sLogMsg) ConsoleWrite("! " & $sLogMsg & @CRLF) $iEnd = StringLen(GUICtrlRead($tMessenger)) _GUICtrlEdit_SetSel($tMessenger, $iEnd, $iEnd) _GUICtrlEdit_Scroll($tMessenger, $SB_SCROLLCARET) $iEnd = StringLen(GUICtrlRead($cDataReceived)) _GUICtrlEdit_SetSel($cDataReceived, $iEnd, $iEnd) _GUICtrlEdit_Scroll($cDataReceived, $SB_SCROLLCARET) EndFunc ;==>_WriteLog Func GetIP($i = "ip") Local $return, $IP = StringSplit(BinaryToString(InetRead("http://api.wipmania.com/")), "<br>", 1) If $i = "from" Then If Not $IP[1] = "" Then $return = $IP[2] Else Return "Error: Api not responding." EndIf Else If Not $IP[1] = "" Then $return = $IP[1] Else Return "Error: Api not responding." EndIf EndIf Return $return EndFunc ;==>GetIP TCP.au3
      #cs ---------------------------------------------------------------------------- AutoIt Version: 3.3.0.0 Author: Kip Script Function: TCP UDF v3 #ce ---------------------------------------------------------------------------- ; Script Start - Add your code below here #cs 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) Register event values: $TCP_SEND ; Function ($hSocket, $iError) $TCP_RECEIVE ; Function ($hSocket, $sReceived, $iError) $TCP_CONNECT ; Function ($hSocket, $iError) => Client only $TCP_DISCONNECT ; Function ($hSocket, $iError) $TCP_NEWCLIENT ; Function ($hSocket, $iError) => Server only #ce Global Const $FD_READ = 1 Global Const $FD_WRITE = 2 Global Const $FD_OOB = 4 Global Const $FD_ACCEPT = 8 Global Const $FD_CONNECT = 16 Global Const $FD_CLOSE = 32 Global $hWs2_32 = -1 Global Const $TCP_SEND = 1 Global Const $TCP_RECEIVE = 2 Global Const $TCP_CONNECT = 4 Global Const $TCP_DISCONNECT = 8 Global Const $TCP_NEWCLIENT = 16 TCPStartup() Global Const $__TCP_WINDOW = GUICreate("Async Sockets UDF") Global $__TCP_SOCKETS[1][7] ; #FUNCTION# ;=============================================================================== ; ; Name...........: _TCP_Server_Create ; Description ...: Initializes the server. ; Syntax.........: _TCP_Server_Create($iPort, $sIP="0.0.0.0") ; Parameters ....: $iPort - The port number the server should listen to. ; $sIP - IP address. (Default = "0.0.0.0") ; Return values .: The socket handle. ; Author ........: Kip ; Modified.......: ; Remarks .......: Only 1 server can be created per script. ; Related .......: ; Link ..........; ; Example .......; ; ; ;========================================================================================== Func _TCP_Server_Create($iPort, $sIP="0.0.0.0") Local $hListenSocket = ___ASocket() ___ASockSelect( $hListenSocket, $__TCP_WINDOW, 0x0400, $FD_ACCEPT) GUIRegisterMsg( 0x0400, "___TCP_OnAccept" ) ___ASockListen( $hListenSocket, $sIP, $iPort ) $__TCP_SOCKETS[0][0] = $hListenSocket $__TCP_SOCKETS[0][1] = 0x0400 Return $hListenSocket EndFunc Func ___TCP_OnAccept($hWnd, $iMsgID, $WParam, $LParam) Local $hSocket = $WParam Local $iError = ___HiWord( $LParam ) Local $iEvent = ___LoWord( $LParam ) Local $hClient, $uBound Abs($hWnd) ; Stupid AU3Check... If $iMsgID = $__TCP_SOCKETS[0][1] Then If $iEvent = $FD_ACCEPT Then If Not $iError Then ReDim $__TCP_SOCKETS[UBound($__TCP_SOCKETS)+1][7] $uBound = UBound($__TCP_SOCKETS) $hClient = TCPAccept($hSocket) ___ASockSelect($hClient, $__TCP_WINDOW, 0x0400 + $uBound - 1, BitOR($FD_READ, $FD_WRITE, $FD_CLOSE)) GUIRegisterMsg(0x0400 + $uBound - 1, "___TCP_Server_OnSocketEvent" ) $__TCP_SOCKETS[UBound($__TCP_SOCKETS)-1][0] = $hClient $__TCP_SOCKETS[UBound($__TCP_SOCKETS)-1][1] = 0x0400 + $uBound - 1 Call($__TCP_SOCKETS[0][6], $hClient, $iError) Else Call($__TCP_SOCKETS[0][6], 0, $iError) EndIf ElseIf $iEvent = $FD_CONNECT Then Call($__TCP_SOCKETS[0][4], $hSocket, $iError) EndIf EndIf EndFunc ; #FUNCTION# ;=============================================================================== ; ; Name...........: _TCP_Client_Stop ; Description ...: Stops the client. ; Syntax.........: _TCP_Client_Stop($hSocket) ; Parameters ....: $hSocket - Client socket. ; Return values .: Success - True ; Failure - False ; Author ........: Kip ; Modified.......: ; Remarks .......: The client socket is the return value of _TCP_Client_Create(). ; Related .......: ; Link ..........; ; Example .......; ; ; ;========================================================================================== Func _TCP_Client_Stop($hSocket) Local $iElement, $i $iElement = 0 For $i = 1 to UBound($__TCP_SOCKETS)-1 If $__TCP_SOCKETS[$i][0] = $hSocket Then $iElement = $i ExitLoop EndIf Next If $iElement Then ___ASockShutdown($__TCP_SOCKETS[$iElement][0]) TCPCloseSocket($__TCP_SOCKETS[$iElement][0]) ___ArrayDelete($__TCP_SOCKETS, $iElement) Return True EndIf Return False EndFunc ; #FUNCTION# ;=============================================================================== ; ; Name...........: _TCP_Server_Stop ; Description ...: Stops the server, and closes all client connections. ; Syntax.........: _TCP_Server_Stop() ; Parameters ....: ; Return values .: True ; Author ........: Kip ; Modified.......: ; Remarks .......: ; Related .......: ; Link ..........; ; Example .......; ; ; ;========================================================================================== Func _TCP_Server_Stop() Local $i ___ASockShutdown($__TCP_SOCKETS[0][0]) TCPCloseSocket($__TCP_SOCKETS[0][0]) $__TCP_SOCKETS[0][0] = "" $__TCP_SOCKETS[0][1] = "" $__TCP_SOCKETS[0][2] = "" $__TCP_SOCKETS[0][3] = "" $__TCP_SOCKETS[0][4] = "" $__TCP_SOCKETS[0][5] = "" $__TCP_SOCKETS[0][6] = "" For $i = UBound($__TCP_SOCKETS)-1 to 1 Step -1 ___ArrayDelete($__TCP_SOCKETS, $i) Next Return True EndFunc Func ___TCP_Server_OnSocketEvent( $hWnd, $iMsgID, $WParam, $LParam ) Local $hSocket = $WParam Local $iError = ___HiWord( $LParam ) Local $iEvent = ___LoWord( $LParam ) Local $sDataBuff, $iElement, $i Abs($hWnd) $hSocket = 0 $iElement = 0 For $i = 1 to UBound($__TCP_SOCKETS)-1 If $__TCP_SOCKETS[$i][1] = $iMsgID Then $hSocket = $__TCP_SOCKETS[$i][0] $iElement = $i ExitLoop EndIf Next If $hSocket Then Switch $iEvent Case $FD_READ $sDataBuff = TCPRecv($hSocket, 1024) Call($__TCP_SOCKETS[0][2], $hSocket, $sDataBuff, $iError) Case $FD_WRITE Call($__TCP_SOCKETS[0][3], $hSocket, $iError) Case $FD_CLOSE ___ASockShutdown($hSocket) TCPCloseSocket($hSocket) Call($__TCP_SOCKETS[0][5], $hSocket, $iError) ___ArrayDelete($__TCP_SOCKETS, $iElement) EndSwitch EndIf EndFunc ; #FUNCTION# ;=============================================================================== ; ; Name...........: _TCP_Server_DisconnectClient ; Description ...: Disconnects a client of the server. ; Syntax.........: _TCP_Server_DisconnectClient($hSocket) ; Parameters ....: $hSocket - Client socket. ; Return values .: Success - True ; Failure - False ; Author ........: Kip ; Modified.......: ; Remarks .......: The client socket is the $hSocket parameter of a _TCP_RegisterEvent callback function. ; Related .......: ; Link ..........; ; Example .......; ; ; ;========================================================================================== Func _TCP_Server_DisconnectClient($hSocket) Local $iElement, $i $iElement = 0 For $i = 1 to UBound($__TCP_SOCKETS)-1 If $__TCP_SOCKETS[$i][0] = $hSocket Then $iElement = $i ExitLoop EndIf Next If $iElement Then ___ASockShutdown($hSocket) TCPCloseSocket($hSocket) ___ArrayDelete($__TCP_SOCKETS, $iElement) Return True EndIf Return False EndFunc ; #FUNCTION# ;=============================================================================== ; ; Name...........: _TCP_Server_ClientList ; Description ...: Returns the sockets of all connected clients. ; Syntax.........: _TCP_Server_ClientList() ; Parameters ....: ; Return values .: An 1 dimensional array of all connected clients. ; Author ........: Kip ; Modified.......: ; Remarks .......: ; Related .......: ; Link ..........; ; Example .......; ; ; ;========================================================================================== Func _TCP_Server_ClientList() Local $aReturn[1], $i For $i = 1 to UBound($__TCP_SOCKETS)-1 If $__TCP_SOCKETS[$i][0] Then ReDim $aReturn[UBound($aReturn)+1] $aReturn[UBound($aReturn)-1] = $__TCP_SOCKETS[$i][0] EndIf Next $aReturn[0] = UBound($aReturn)-1 Return $aReturn EndFunc ; #FUNCTION# ;=============================================================================== ; ; Name...........: _TCP_Server_Broadcast ; Description ...: Sends data to all connected clients. ; Syntax.........: _TCP_Server_Broadcast($sData) ; Parameters ....: $sData - The data to send. ; Return values .: True ; Author ........: Kip ; Modified.......: ; Remarks .......: ; Related .......: ; Link ..........; ; Example .......; ; ; ;========================================================================================== Func _TCP_Server_Broadcast($sData) Local $i For $i = 1 to UBound($__TCP_SOCKETS)-1 If $__TCP_SOCKETS[$i][0] Then TCPSend($__TCP_SOCKETS[$i][0], $sData) Next Return True EndFunc ; #FUNCTION# ;=============================================================================== ; ; Name...........: _TCP_Client_Create ; Description ...: Creates a new client. ; Syntax.........: _TCP_Client_Create($sIP , $iPort) ; Parameters ....: $sIP - The IP address to connect to. ; $iPort - Port on which the created socket will be connected. ; Return values .: Client socket handle. ; Author ........: Kip ; Modified.......: ; Remarks .......: ; Related .......: ; Link ..........; ; Example .......; ; ; ;========================================================================================== Func _TCP_Client_Create($sIP , $iPort) ReDim $__TCP_SOCKETS[UBound($__TCP_SOCKETS)+1][7] local $hSocket = ___ASocket() $__TCP_SOCKETS[UBound($__TCP_SOCKETS)-1][0] = $hSocket $__TCP_SOCKETS[UBound($__TCP_SOCKETS)-1][1] = 0x0400 + (UBound($__TCP_SOCKETS)-1) ___ASockSelect( $hSocket, $__TCP_WINDOW, 0x0400 + (UBound($__TCP_SOCKETS)-1), BitOR( $FD_READ, $FD_WRITE, $FD_CONNECT, $FD_CLOSE ) ) GUIRegisterMsg( 0x0400 + (UBound($__TCP_SOCKETS)-1), "___TCP_Client_OnSocketEvent" ) ___ASockConnect( $hSocket, $sIP, $iPort ) Return $hSocket EndFunc ; #FUNCTION# ;=============================================================================== ; ; Name...........: _TCP_RegisterEvent ; Description ...: Registers an event. ; Syntax.........: _TCP_RegisterEvent($hSocket, $iEvent, $sFunction) ; Parameters ....: $hSocket - Socket of the server or a client. ; $iEvent - Event number. It can be any these values: ; * $TCP_SEND ; * $TCP_RECEIVE ; * $TCP_CONNECT => Client only ; * $TCP_DISCONNECT ; * $TCP_NEWCLIENT => Server only ; Return values .: Success - True ; Failure - False ; Author ........: Kip ; Modified.......: ; Remarks .......: ; Related .......: ; Link ..........; ; Example .......; ; ; ;========================================================================================== Func _TCP_RegisterEvent($hSocket, $iEvent, $sFunction) Local $iSelected = 0 Local $i If $__TCP_SOCKETS[0][0] Then $iSelected = 0 Else For $i = 0 to UBound($__TCP_SOCKETS)-1 If $__TCP_SOCKETS[$i][0] = $hSocket Then $iSelected = $i ExitLoop EndIf Next If Not $iSelected Then Return 0 EndIf Switch $iEvent Case $TCP_SEND $__TCP_SOCKETS[$iSelected][3] = $sFunction Case $TCP_RECEIVE $__TCP_SOCKETS[$iSelected][2] = $sFunction Case $TCP_CONNECT $__TCP_SOCKETS[$iSelected][4] = $sFunction Case $TCP_DISCONNECT $__TCP_SOCKETS[$iSelected][5] = $sFunction Case $TCP_NEWCLIENT $__TCP_SOCKETS[$iSelected][6] = $sFunction Case Else Return False EndSwitch Return True EndFunc ; #FUNCTION# ;=============================================================================== ; ; Name...........: _TCP_Server_ClientIP ; Description ...: Converts a client socket handle to IP address. ; Syntax.........: _TCP_Server_ClientIP($hSocket) ; Parameters ....: $hSocket - Client socket handle. ; Return values .: A string with the IP address. ; Author ........: Unknown ; Modified.......: Kip ; Remarks .......: ; Related .......: ; Link ..........; ; Example .......; ; ; ;========================================================================================== Func _TCP_Server_ClientIP($hSocket) Local $pSocketAddress, $aReturn $pSocketAddress = DllStructCreate("short;ushort;uint;char[8]") $aReturn = DllCall("Ws2_32.dll", "int", "getpeername", "int", $hSocket, "ptr", DllStructGetPtr($pSocketAddress), "int*", DllStructGetSize($pSocketAddress)) If @error Or $aReturn[0] <> 0 Then Return 0 $aReturn = DllCall("Ws2_32.dll", "str", "inet_ntoa", "int", DllStructGetData($pSocketAddress, 3)) If @error Then Return 0 $pSocketAddress = 0 Return $aReturn[0] EndFunc ; #FUNCTION# ;=============================================================================== ; ; Name...........: _TCP_Send ; Description ...: Sends data to a server or client. ; Syntax.........: _TCP_Send($hSocket, $sText) ; Parameters ....: $hSocket - Client or server socket handle. ; $sText - Data to send. ; Return values .: ; Author ........: Kip ; Modified.......: ; Remarks .......: ; Related .......: ; Link ..........; ; Example .......; ; ; ;========================================================================================== Func _TCP_Send($hSocket, $sText) Return TCPSend($hSocket, $sText) EndFunc Func ___TCP_Client_OnSocketEvent( $hWnd, $iMsgID, $WParam, $LParam ) Local $iError = ___HiWord( $LParam ) Local $iEvent = ___LoWord( $LParam ) Local $hSocket, $iElement, $i, $sDataBuff Abs($hWnd) Abs($WParam) $hSocket = 0 $iElement = 0 For $i = 1 to UBound($__TCP_SOCKETS)-1 If $__TCP_SOCKETS[$i][1] = $iMsgID Then $hSocket = $__TCP_SOCKETS[$i][0] $iElement = $i ExitLoop EndIf Next If $hSocket Then Switch $iEvent Case $FD_READ; Data has arrived! $sDataBuff = TCPRecv( $hSocket, 1024) Call($__TCP_SOCKETS[$i][2], $hSocket, $sDataBuff, $iError) $sDataBuff = "" Case $FD_WRITE Call($__TCP_SOCKETS[$i][3], $hSocket, $iError) Case $FD_CONNECT Call($__TCP_SOCKETS[$i][4], $hSocket, $iError) Case $FD_CLOSE ___ASockShutdown( $hSocket ) TCPCloseSocket( $hSocket ) Call($__TCP_SOCKETS[$i][5], $hSocket, $iError) ___ArrayDelete($__TCP_SOCKETS, $iElement) EndSwitch EndIf EndFunc ;================================================================================================================== ; ; Zatorg's Asynchronous Sockets UDF Starts from here. ; ;================================================================================================================== Func ___ASocket($iAddressFamily = 2, $iType = 1, $iProtocol = 6) If $hWs2_32 = -1 Then $hWs2_32 = DllOpen( "Ws2_32.dll" ) Local $hSocket = DllCall($hWs2_32, "uint", "socket", "int", $iAddressFamily, "int", $iType, "int", $iProtocol) If @error Then SetError(1, @error) Return -1 EndIf If $hSocket[ 0 ] = -1 Then SetError(2, ___WSAGetLastError()) Return -1 EndIf Return $hSocket[ 0 ] EndFunc ;==>_ASocket Func ___ASockShutdown($hSocket) If $hWs2_32 = -1 Then $hWs2_32 = DllOpen( "Ws2_32.dll" ) Local $iRet = DllCall($hWs2_32, "int", "shutdown", "uint", $hSocket, "int", 2) If @error Then SetError(1, @error) Return False EndIf If $iRet[ 0 ] <> 0 Then SetError(2, ___WSAGetLastError()) Return False EndIf Return True EndFunc ;==>_ASockShutdown Func ___ASockClose($hSocket) If $hWs2_32 = -1 Then $hWs2_32 = DllOpen( "Ws2_32.dll" ) Local $iRet = DllCall($hWs2_32, "int", "closesocket", "uint", $hSocket) If @error Then SetError(1, @error) Return False EndIf If $iRet[ 0 ] <> 0 Then SetError(2, ___WSAGetLastError()) Return False EndIf Return True EndFunc ;==>_ASockClose Func ___ASockSelect($hSocket, $hWnd, $uiMsg, $iEvent) If $hWs2_32 = -1 Then $hWs2_32 = DllOpen( "Ws2_32.dll" ) Local $iRet = DllCall( _ $hWs2_32, _ "int", "WSAAsyncSelect", _ "uint", $hSocket, _ "hwnd", $hWnd, _ "uint", $uiMsg, _ "int", $iEvent _ ) If @error Then SetError(1, @error) Return False EndIf If $iRet[ 0 ] <> 0 Then SetError(2, ___WSAGetLastError()) Return False EndIf Return True EndFunc ;==>_ASockSelect ; Note: you can see that $iMaxPending is set to 5 by default. ; IT DOES NOT MEAN THAT DEFAULT = 5 PENDING CONNECTIONS ; 5 == SOMAXCONN, so don't worry be happy Func ___ASockListen($hSocket, $sIP, $uiPort, $iMaxPending = 5); 5 == SOMAXCONN => No need to change it. Local $iRet Local $stAddress If $hWs2_32 = -1 Then $hWs2_32 = DllOpen( "Ws2_32.dll" ) $stAddress = ___SockAddr($sIP, $uiPort) If @error Then SetError(@error, @extended) Return False EndIf $iRet = DllCall($hWs2_32, "int", "bind", "uint", $hSocket, "ptr", DllStructGetPtr($stAddress), "int", DllStructGetSize($stAddress)) If @error Then SetError(3, @error) Return False EndIf If $iRet[ 0 ] <> 0 Then $stAddress = 0; Deallocate SetError(4, ___WSAGetLastError()) Return False EndIf $iRet = DllCall($hWs2_32, "int", "listen", "uint", $hSocket, "int", $iMaxPending) If @error Then SetError(5, @error) Return False EndIf If $iRet[ 0 ] <> 0 Then $stAddress = 0; Deallocate SetError(6, ___WSAGetLastError()) Return False EndIf Return True EndFunc ;==>_ASockListen Func ___ASockConnect($hSocket, $sIP, $uiPort) Local $iRet Local $stAddress If $hWs2_32 = -1 Then $hWs2_32 = DllOpen( "Ws2_32.dll" ) $stAddress = ___SockAddr($sIP, $uiPort) If @error Then SetError(@error, @extended) Return False EndIf $iRet = DllCall($hWs2_32, "int", "connect", "uint", $hSocket, "ptr", DllStructGetPtr($stAddress), "int", DllStructGetSize($stAddress)) If @error Then SetError(3, @error) Return False EndIf $iRet = ___WSAGetLastError() If $iRet = 10035 Then; WSAEWOULDBLOCK Return True; Asynchronous connect attempt has been started. EndIf SetExtended(1); Connected immediately Return True EndFunc ;==>_ASockConnect ; A wrapper function to ease all the pain in creating and filling the sockaddr struct Func ___SockAddr($sIP, $iPort, $iAddressFamily = 2) Local $iRet Local $stAddress If $hWs2_32 = -1 Then $hWs2_32 = DllOpen( "Ws2_32.dll" ) $stAddress = DllStructCreate("short; ushort; uint; char[8]") If @error Then SetError(1, @error) Return False EndIf DllStructSetData($stAddress, 1, $iAddressFamily) $iRet = DllCall($hWs2_32, "ushort", "htons", "ushort", $iPort) DllStructSetData($stAddress, 2, $iRet[ 0 ]) $iRet = DllCall($hWs2_32, "uint", "inet_addr", "str", $sIP) If $iRet[ 0 ] = 0xffffffff Then; INADDR_NONE $stAddress = 0; Deallocate SetError(2, ___WSAGetLastError()) Return False EndIf DllStructSetData($stAddress, 3, $iRet[ 0 ]) Return $stAddress EndFunc ;==>__SockAddr Func ___WSAGetLastError() If $hWs2_32 = -1 Then $hWs2_32 = DllOpen( "Ws2_32.dll" ) Local $iRet = DllCall($hWs2_32, "int", "WSAGetLastError") If @error Then ;ConsoleWrite("+> _WSAGetLastError(): WSAGetLastError() failed. Script line number: " & @ScriptLineNumber & @CRLF) SetExtended(1) Return 0 EndIf Return $iRet[ 0 ] EndFunc ;==>_WSAGetLastError ; Got these here: ; http://www.autoitscript.com/forum/index.php?showtopic=5620&hl=MAKELONG Func ___MakeLong($LoWord, $HiWord) Return BitOR($HiWord * 0x10000, BitAND($LoWord, 0xFFFF)); Thanks Larry EndFunc ;==>_MakeLong Func ___HiWord($Long) Return BitShift($Long, 16); Thanks Valik EndFunc ;==>_HiWord Func ___LoWord($Long) Return BitAND($Long, 0xFFFF); Thanks Valik EndFunc ;==>_LoWord ; ========================================= Array functions ; #FUNCTION# ==================================================================================================================== ; Name...........: _ArrayDelete ; Description ...: Deletes the specified element from the given array. ; Syntax.........: _ArrayDelete(ByRef $avArray, $iElement) ; Parameters ....: $avArray - Array to modify ; $iElement - Element to delete ; Return values .: Success - New size of the array ; Failure - 0, sets @error to: ; |1 - $avArray is not an array ; |3 - $avArray has too many dimensions (only up to 2D supported) ; |(2 - Deprecated error code) ; Author ........: Cephas <cephas at clergy dot net> ; Modified.......: Jos van der Zande <jdeb at autoitscript dot com> - array passed ByRef, Ultima - 2D arrays supported, reworked function (no longer needs temporary array; faster when deleting from end) ; Remarks .......: If the array has one element left (or one row for 2D arrays), it will be set to "" after _ArrayDelete() is used on it. ; Related .......: _ArrayAdd, _ArrayInsert, _ArrayPop, _ArrayPush ; Link ..........; ; Example .......; Yes ; =============================================================================================================================== Func ___ArrayDelete(ByRef $avArray, $iElement) If Not IsArray($avArray) Then Return SetError(1, 0, 0) Local $iUBound = UBound($avArray, 1) - 1 If Not $iUBound Then $avArray = "" Return 0 EndIf ; Bounds checking If $iElement < 0 Then $iElement = 0 If $iElement > $iUBound Then $iElement = $iUBound ; Move items after $iElement up by 1 Switch UBound($avArray, 0) Case 1 For $i = $iElement To $iUBound - 1 $avArray[$i] = $avArray[$i + 1] Next ReDim $avArray[$iUBound] Case 2 Local $iSubMax = UBound($avArray, 2) - 1 For $i = $iElement To $iUBound - 1 For $j = 0 To $iSubMax $avArray[$i][$j] = $avArray[$i + 1][$j] Next Next ReDim $avArray[$iUBound][$iSubMax + 1] Case Else Return SetError(3, 0, 0) EndSwitch Return $iUBound EndFunc ;==>_ArrayDelete  
      Problem:
      - Can not send and receive between Client and Server!
      - Data loss, data reception is not complete.