Jump to content

Multiple TCP connections...


Recommended Posts

So I was working with TCP and all, its fairly fun.

But what I can't figure out, is how to allow multiple connections on one port (if possible). I was looking at the sample scripts AutoIt Smith posted in Scripts and Scraps, but they only allow one connection ( well, I tryed opening two clients on the same computer as the server, the first one responded, the second, or any after, did not ).

Sorry if its been answered, but any help/links would be nice.

Thanks,

-Daikenkaiking

Link to comment
Share on other sites

Here's a function I wrote some time ago which tries to make handling of multiple

connections easier. As you can see the documentation for it is almost as long the

code itself, so I hope it's easy to get used to. Basically just replace the TCPAccept-

part in your code with this function and then rewrite your script to support the arrays.

#include <Array.au3>



;===============================================================================
;
; Function Name:    _TCPAutoSocket
; Description:      This function uses TCPAccept to check for new connections, and
;                   automatically adds and removes the sockets from an array as they
;                   connect and disconnect. It also automatically creates arrays
;                   containing the newly connected and disconnected sockets, giving
;                   you more {and needed} control of your server.
;
; Parameter(s):     $aSockets   - Array to store all connected sockets in (see notes).
;                   $aNewConn   - Array to store the newly connected sockets in (see notes).
;                   $aNewDisc   - Array to store the newly disconnected sockets in (see notes).
;                   $iSockMain  - Socket returned by TCPListen.
;                   $iMaxConn   - Optional : max number of connected sockets to allow. Default is -1 (see notes).
;
; Requirement(s):   Array.au3
; Return Value(s):  Success :   Returns 1.
;                   Failure :   Returns 0 and sets @error to 1 if TCPAccept failed.
;
; Note(s):          $aSockets holds all of the connected sockets, while $aNewConn only
;                   holds the newly connected sockets, accepted and added last time
;                   _TCPAutoSocket was called. $aNewDisc however holds the sockets
;                   that has disconnected since last time, and it's strongly advised
;                   to check this array first. The first element ($array[0]) in all
;                   of the arrays equals the number of sockets in the array.
;
;                   The default value (-1) for $iMaxConn can be used if you don't want
;                   to have a upper limit for the number of connected sockets, while 0
;                   can be used if you don't want to allow any new connections at all.
;                   Any other number will be an actual limit, meaning that if the number
;                   of connected sockets reaches this limit then no more connection-
;                   attempts will be accepted.
;
; Author(s):        Helge
;
;===============================================================================
Func _TCPAutoSocket(ByRef $aSockets, ByRef $aNewConn, ByRef $aNewDisc, $iSockMain, $iMaxConn = -1)
    If Not IsArray($aSockets) Then Dim $aSockets[1] = [0]
    If Not IsArray($aNewConn) Then Dim $aNewConn[1]
    If Not IsArray($aNewDisc) Then Dim $aNewDisc[1]
    
    Local $iSockConn, $i = 1
    ReDim $aNewConn[1], $aNewDisc[1]
    $aNewConn[0] = 0
    $aNewDisc[0] = 0
    
    If UBound($aSockets) > 1 Then
        While 1
            If $aSockets[0] < $i Then ExitLoop
            TCPSend ($aSockets[$i], "")
            If @error Then
                TCPCloseSocket ($aSockets[$i])
                
                _ArrayAdd($aNewDisc, $aSockets[$i])
                $aNewDisc[0] += 1
                
                _ArrayDelete($aSockets, $i)
                $aSockets[0] -= 1
            Else
                $i += 1
            EndIf
        WEnd
    EndIf
    
    Do
        $iSockConn = TCPAccept ($iSockMain)
        If @error Then
            SetError(1)
            Return 0
        EndIf
        
        If $iSockConn <> - 1 Then
            If $iMaxConn = -1 Or $aSockets[0] < $iMaxConn And $iMaxConn <> 0 Then
                _ArrayAdd($aNewConn, $iSockConn)
                $aNewConn[0] += 1
                
                _ArrayAdd($aSockets, $iSockConn)
                $aSockets[0] += 1
            Else
                TCPCloseSocket ($iSockConn)
            EndIf
        EndIf
    Until $iSockConn = -1
    
    Return 1
EndFunc   ;==>_TCPAutoSocket

Edit: it's been a while since I touched TPC, so there might be some issues with the

function, however I haven't had any problems with it yet.

Edited by Helge
Link to comment
Share on other sites

Well, that sound like a job for _TCPRecvAll :lmao:

UDF first, followed by modified sample-code. Untested but should work.

UDF : _TCPRecvAll

;===============================================================================
;
; Function Name:    _TCPRecvAll
; Description:      Checks for received data from all connected sockets, and returns a
;                   two-dimensional array with the received data and the senders' sockets.
;
; Parameter(s):     $aSockets   - The array created by _TCPAutoSocket.
;                   $iMaxLen    - Optional : max # of characters to receive from one socket. Default is 256.
;
; Return Value(s):  Success : Returns a two dimensional array :
;                       $array[0][0] - number of sockets who's data is received from.
;                       $array[x][0] - sender's socket.
;                       $array[x][1] - received data.
;
;                   Failure : @error is set :
;                       1 - $aSockets wasn't an array.
;                       2 - Every attempt to receive failed.
;
; Note(s):          @extended holds the number of failed attempts to receive, and if this
;                   number equals the number of connected sockets then @error is set to 2.
;
; Author(s):        Helge
;
;===============================================================================
Func _TCPRecvAll($aSockets, $iMaxLen = 256)
    Local $vRecv, $vRecvNew, $iFailed = 0
    Local $aReturn[1][1] = [[0]]
    
    If UBound($aSockets) < 1 Then
        If UBound($aSockets) = 0 Then SetError(1)
        Return $aReturn
    EndIf
    
    For $i = 1 To $aSockets[0]
        $vRecv = ""
        Do
            $vRecvNew = TCPRecv ($aSockets[$i], $iMaxLen - StringLen($vRecv))
            If @error Then $iFailed += 1
            
            $vRecv &= $vRecvNew
        Until $vRecvNew = ""
        
        If $vRecv <> "" Then
            $aReturn[0][0] += 1
            ReDim $aReturn[UBound($aReturn) + 1][2]
            $aReturn[UBound($aReturn) - 1][0] = $aSockets[$i]
            $aReturn[UBound($aReturn) - 1][1] = $vRecv
        EndIf
    Next
    
    If $iFailed < $aSockets[0] Then
        SetError(0, $iFailed)
    Else
        SetError(2, $iFailed)
    EndIf
    
    Return $aReturn
EndFunc   ;==>_TCPRecvAlloÝ÷ ÚæÒjjeyÊ{öÿ¹«­¢+Ø¥¹±Õ±ÐíÉÉä¹ÔÌÐì()±½°
½¹ÍÐÀÌØí%@ô%AIMLÄ)±½°
½¹ÍÐÀÌØíA=IPôÄÀÀÀ()±½°ÀÌØí±¥ÍѸ)±½°ÀÌØí±¥ÍÐ)±½°ÀÌØí¹Ü)±½°ÀÌØí½±(()Q
AMÑÉÑÕÀ ¤((ÀÌØí±¥ÍѸôQ
A1¥ÍѸ ÀÌØí%@°ÀÌØíA=IP°Äܤ)%ÀÌØí±¥ÍѸô´ÄQ¡¸ÉÉ½È ÅÕ½ÐíU¹±Ñ¼½¹¹Ð¸ÅÕ½Ðì°Ä¤()Ý¡¥±Ä(%M±À ÄÀ¤ì±½ÝÈ
ATµÕÍ($(}Q
AÕѽM½­Ð ÀÌØí±¥ÍаÀÌØí¹Ü°ÀÌØí½±°ÀÌØí±¥ÍѸ°´Ä¤($(%%ÀÌØí±¥ÍÑlÁtÐìÀQ¡¸ì±¥¹Ñ̽¹¹Ñü($$($$ÀÌØíÉØô}Q
AIÙ±° ÀÌØíM½­Ñ̤($%%ÀÌØíÉÙlÁulÁtÐìÀQ¡¸ìÑÉ¥Ùü($$$ìÍ¡½Ü½ÁɽÍÌÑ($%¹%((%¹%$)]¹
Link to comment
Share on other sites

Not to sound too noob or anything, but would woudl the call look like?

Mines giving me errors, sort of confusing ( sorry, i'm new to this TCP thing :ph34r: ).

EDIT: Okay, I got it working, thanks for the help man. :lmao:

EDIT2:

Okay, this is what I got:

#include <Array.au3>

Global Const $IP = @IPADDRESS1
Global Const $PORT = 1000

Global $listen
Global $list
Global $new
Global $old


TCPStartup()

$listen = TCPListen($IP, $PORT, 17)
If $listen = -1 Then Error("Unable to connect.", 1)

while 1
    _TCPAutoSocket( $list, $new, $old, $listen, -1 )
WEnd

<your code here>

How would I Run through to check the Data coming from each connectioN?

Link to comment
Share on other sites

I would suggest you to do some reading and testing with arrays.

Anyway, try something like this :

#include <Array.au3>

Global Const $IP = @IPADDRESS1
Global Const $PORT = 1000

Global $listen
Global $list
Global $new
Global $old


TCPStartup()

$listen = TCPListen($IP, $PORT, 17)
If $listen = -1 Then Error("Unable to connect.", 1)

while 1
    Sleep(10) ; lower CPU-usage
   
    _TCPAutoSocket( $list, $new, $old, $listen, -1 )
   
    If $list[0] > 0 Then ; clients connected ?
       
        $recv = _TCPRecvAll($aSockets)
        If $recv[0][0] > 0 Then ; data receieved ?
            
            For $i = 1 To $recv[0][0] ; go thru received data
                MsgBox(64, "", "socket " & $recv[$i][0] & " sent : " & $recv[$i][1])
            Next
        EndIf

    EndIf   
WEnd
Link to comment
Share on other sites

Nah, I can use arrays just fine ( pretty much the same as PHP, and I use PHP quite often ), I just wasen't sure of how you stored them, and your code was -alittle- over my head.

Thanks very much, you have helped me greatly. :ph34r::lmao:

-Daikenkaiking

EDIT: Now it says "_TCPRecvAll" is not a fucntion. :)

EDIT2: Nevermind, I clearly missed your post, sorry. :geek:

Edited by Daikenkaiking
Link to comment
Share on other sites

Create an account or sign in to comment

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

Create an account

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

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

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