Jump to content

TCP Command Receiving Server


LarryDalooza
 Share

Recommended Posts

I needed to create a remote command server.

I have a 3 ELEMENT ARRAY for each socket that includes a BOOLEAN element that ticks ON when you have sent successful logon credential info.

What I have included is a SERVER and a CLIENT. And the SERVER just does whatever the CLIENT says to do.

The SERVER accepts (binary) info in the format...

- 4byte command

- 4byte length of data

- variable length data

The SERVER Function "React()" can be modified for your command set.

A client script is supplied for example usage.

PS. If you don't know about port forwarding, search the forum before asking.

TCPStartup()

Global Const $ID_nobodyThere = -1
Global Const $ID_Password = Binary("SecretPassword")
Global $party[1][3]
Global $frontDoor = TCPListen(@IPAddress1,41421)

While 1
    KnockKnock()
    WhatsUp()
WEnd

Func React($partyGoer,$cmd,$rawData)
    If $party[$partyGoer][1] Or ($cmd = 1) Then
        Switch $cmd
            case 1
                If $rawData = $ID_Password Then
                    $party[$partyGoer][1] = True
                    TCPSend($party[$partyGoer][0],Binary(1))
                Else
                    $party[$partyGoer][1] = False
                    TCPSend($party[$partyGoer][0],Binary(0))
                EndIf
            case 2
                TrayTip("","Filename" & @LF & @LF & BinaryToString($rawData),5)
                TCPSend($party[$partyGoer][0],Binary(1))
            case 3
                If Run(BinaryToString($rawdata)) Then
                    TCPSend($party[$partyGoer][0],Binary(1))
                Else
                    TCPSend($party[$partyGoer][0],Binary(0))
                EndIf   
            case 4
                TCPSend($party[$partyGoer][0],Binary(1))
                Sleep(2000)
                TCPShutDown()
                Exit
            case 5
                FileWrite(@ScriptDir & "\Some.bmp",$rawData)
                TCPSend($party[$partyGoer][0],Binary(1))
        EndSwitch
    Else
        TCPSend($party[$partyGoer][0],Binary(0))
    EndIf
EndFunc

Func KnockKnock()
    Sleep(5)
   
    Local $whoseThere = TCPAccept($frontDoor)
    If $whoseThere = $ID_nobodyThere Then Return SetError(0,0,0)
   
    AddToParty($whoseThere)
EndFunc

Func WhatsUp()
    Local $conversation,$person=1
   
    While $person <= $party[0][0]
        $conversation = TCPRecv($party[$person][0],200000)
        If @error Then
            SomeoneLeftTheParty($person)
            $person -= 1
        ElseIf BinaryLen($conversation) Then
            ConverseWith($person,Binary($conversation))
        EndIf
        $person += 1
    WEnd
EndFunc

Func ConverseWith($partyAnimal, $blabber)
    Local $subject,$length,$data,$dataLen
   
    $party[$partyAnimal][2] &= $blabber
   
    $dataLen = BinaryLen($party[$partyAnimal][2])
    While $dataLen >= 8
        $length = Bin2Num(BinaryMid($party[$partyAnimal][2],5,4))
        If $dataLen < ($length + 8) Then Return SetError(0,0,0)
        $subject = Bin2Num(BinaryMid($party[$partyAnimal][2],1,4))
        $data = BinaryMid($party[$partyAnimal][2],9,$length)
        $party[$partyAnimal][2] = BinaryMid($party[$partyAnimal][2],$length+9,$dataLen-($length+8))
        React($partyAnimal,$subject,$data)
        $dataLen = BinaryLen($party[$partyAnimal][2])
    WEnd
EndFunc

Func SomeoneLeftTheParty($partyPooper)
    Local $partyAnimal
   
    TCPCloseSocket($party[$partyPooper][0])
   
    If Not ($partyPooper = $party[0][0]) Then
        For $partyAnimal = $partyPooper To ($party[0][0] - 1)
            $party[$partyAnimal][0] = $party[$partyAnimal+1][0]
            $party[$partyAnimal][1] = $party[$partyAnimal+1][1]
            $party[$partyAnimal][2] = $party[$partyAnimal+1][2]
        Next
    EndIf
    Redim $party[$party[0][0]][3]
    $party[0][0] -= 1
EndFunc

Func AddToParty($partyMember)
    Local $partyMembers = Ubound($party)
   
    ReDim $party[$partyMembers+1][4]
   
    $party[0][0] += 1
    $party[$partyMembers][0] = $partyMember
    $party[$partyMembers][1] = False
    $party[$partyMembers][2] = Binary($party[$partyMembers][2])
EndFunc

Func Bin2Num($4bytes)
    $dllStruct2_Integer = DllStructCreate("int")
    $dllStruct2_Binary = DllStructCreate("byte[4]", DllStructGetPtr($dllStruct2_Integer))

    DllStructSetData($dllStruct2_Binary,1,$4bytes)
    Return DllStructGetData($dllStruct2_Integer, 1)
EndFuncoÝ÷ Ù«­¢+Øí
1%9P´¹¼
5Ý¥±°Ý½É¬Õ¹Ñ¥°å½Ô͹
5ĹѡAÍÍݽÉ)Q
AMÑÉÑÕÀ ¤()±½°ÀÌØíͽ¬ôQ
A
½¹¹Ð ÅÕ½ÐìÄÀ¸ÄÀ¸ÄÀ¸ÈÄÅÕ½Ðì°ÐÄÐÈĤ)±½°ÀÌØí¥¹Éå¬(ÀÌØí¥¹Éå¬ô ¥¹Éä ÀÌØí¥¹É嬤((ì
=559̹ѡÉոͽµÑ¡¥¹¤9=P½¥¹Ñ¼Ý½É¬¸¸±½¥¸¥ÉÍÐ)%9½ÐM¹Q½MÉÙÈ Ì°ÅÕ½Ðí¹½ÑÁÅÕ½Ðì¤Q¡¸5Í  ½à ÐÀäرÉɽȰÅÕ½Ðí¥±Ñ¼IÕ¸ÅÕ½ÐìÅÕ½Ðí9=QAÅÕ½ÐìÅÕ½Ð콸MÉÙÈÅÕ½Ðì¤((ì
=559Ĺѡ1½½¸¤)%M¹Q½MÉÙÈ Ä°ÅÕ½ÐíMÉÑAÍÍݽÉÅÕ½Ðì¤Q¡¸5Í ½à ÐÀäرÉɽȰÅÕ½ÐíMÕÍÍÕ±±ä1½%¸ÅÕ½Ðì¤((ì
=559̹ѡÉոͽµÑ¡¥¹¤)%M¹Q½MÉÙÈ Ì°ÅÕ½Ðí±ÅÕ½Ðì¤Q¡¸5Í  ½à ÐÀäرÉɽȰÅÕ½ÐíMÕÍÍÕ±±äI¸ÅÕ½ÐìÅÕ½Ðí
1ÅÕ½ÐìÅÕ½Ð콸MÉÙÈÅÕ½Ðì¤((ÀÌØíô¥±I ÅÕ½Ðì¸ÀäÈíM½´¹µÀÅÕ½Ðì¤)%M¹Q½MÉÙÈ Ô°ÀÌØí¤Q¡¸5Í ½à ÐÀäرÉɽȰÅÕ½ÐíMÕÍÍÕ±±äM¹ÐM½µ¹µÀÅÕ½Ðì¤((ì
=559йѡa%P¤)%M¹Q½MÉÙÈ Ð°ÅÕ½ÐìÅÕ½Ðì¤Q¡¸5Í ½à ÐÀäرÉɽȰÅÕ½ÐíMÕÍÍÕ±±äM¹ÐÅÕ½ÐìÅÕ½Ðía%PÅÕ½ÐìÅÕ½ÐìMÉÙÈ
½µµ¹ÅÕ½Ðì¤()Õ¹M¹Q½MÉÙÈ ÀÌØí½µµ¹°ÀÌØí½µµ¹Ñ¤(1½°ÀÌØíÉаÀÌØí¸°ÀÌØí¤ôÀ(1½°ÀÌØí¥¹ÉåÑô  ¥¹Éä ÀÌØí½µµ¹¤µÀì   ¥¹Éä¡  ¥¹Éå1¸ ÀÌØí½µµ¹Ñ¤¤µÀì    ¥¹Éä ÀÌØí½µµ¹Ñ¤((]¡¥±  ¥¹Éå1¸ ÀÌØí¥¹ÉåѤ(ÀÌØí¸ôQ
AM¹ ÀÌØíͽ¬°ÀÌØí¥¹ÉåѤ(%ÀÌØí¸ÐìÀQ¡¸(ÀÌØí¥¹ÉåÑô   ¥¹Éå5¥ ÀÌØí¥¹ÉåÑ°ÀÌØí¸¬Ä±    ¥¹Éå1¸ ÀÌØí¥¹ÉåѤ´ÀÌØí¸¤(¹%(M±À Ô¤(ÀÌØí¤¬ôÄ(%ÀÌØí¤ôÄÀÀÀQ¡¸á¥ÐìII=]!P!10°ÑÉ¥ÄÀÀÀÑ¥µÌ(]¹(ÀÌØíÉÐô¬ ¤(IÑÕɸMÑÉɽȡÉɽȰÀ°ÀÌØíÉФ)¹Õ¹()Õ¹¬ ¤(1½°ÀÌØíÉаÀÌØí¸ôÄ(]¡¥±Ä(ÀÌØí¥¹É嬵ÀìôQ
AIØ ÀÌØíͽ¬°ÈÀÀÀÀÀ¤(%   ¥¹Éå1¸ ÀÌØí¥¹É嬤ÐìôÐQ¡¸á¥Ñ1½½À(M±À ÄÀ¤(ÀÌØí¸¬ôÄ(%ÀÌØí¸ôÄÀÀÀQ¡¸IÑÕɸMÑÉÉ½È Ä°À°À¤(]¹(ÀÌØíÉÐô ¥¹Éå5¥ ÀÌØí¥¹É嬰İФ(ÀÌØí¥¹Éå¬ô   ¥¹Éå5¥ ÀÌØí¥¹É嬰Ա    ¥¹Éå1¸ ÀÌØí¥¹É嬴Ф¤(IÑÕɸ ÀÌØíÉÐô ¥¹Éä Ĥ¤)¹Õ¹

Edit: edit on this forum scrambles "autoit" code tags... annoying.

Edit: Added Password... No interact works before password is sent

Edit: Added Acknowledgment to be received by CLIENT

Edit: Turns out TCPRecv needs to have it's return cast to Binary()

Sent 1 meg file in three seconds

Edit: Fixed Multiple Connection Handling... I hope

Edited by LarryDalooza

f_mrcleansmalm_77ce002.jpgAutoIt has helped make me wealthy

Link to comment
Share on other sites

For data transfer to Server you can edit React() to...

case 5
                FileWrite(@ScriptDir & "\Some.exe",$rawData)
                TCPSend($party[$partyGoer][0],Binary(1))oÝ÷ Ù«­¢+ØÀÌØíô¥±I ÅÕ½Ðì¸ÀäÈíM½µ¹áÅÕ½Ðì¤)%M¹Q½MÉÙÈ Ô°ÀÌØí¤Q¡¸5Í    ½à ÐÀäرÉɽȰÅÕ½ÐíMÕÍÍÕ±±äM¹ÐM½µ¹áÅÕ½Ðì
Edited by LarryDalooza

f_mrcleansmalm_77ce002.jpgAutoIt has helped make me wealthy

Link to comment
Share on other sites

excellent code as usual Larry, Thanks for shareing.

I have a question , in the React() Function on the server, you have case 4 (close) setup to exit the script. Is this the only way to close that connection? what if you have multiple $partymember? How would you just shutdown the connection for the one Party member?

There is always a butthead in the crowd, no matter how hard one tries to keep them out.......Volly

Link to comment
Share on other sites

excellent code as usual Larry, Thanks for shareing.

I have a question , in the React() Function on the server, you have case 4 (close) setup to exit the script. Is this the only way to close that connection? what if you have multiple $partymember? How would you just shutdown the connection for the one Party member?

Everything in React() is example code... you can set up your commands to do whatever you want. Clients are removed from the socket array when they close their connection on their end.

Lar.

f_mrcleansmalm_77ce002.jpgAutoIt has helped make me wealthy

Link to comment
Share on other sites

  • 2 weeks later...

Some bug in the server. I will try to fix when I get some time. I am getting corrupted data.

Lar.

I haven't actually tried this but the code looks really good. ;)

How is it going with the bug you are talking about, is it fixed?

Link to comment
Share on other sites

I haven't actually tried this but the code looks really good. ;)

How is it going with the bug you are talking about, is it fixed?

When sending large amounts of data (files) the data gets corrupted. I am going to add logic to break up data into smaller pieces and revisit my data validation as it is muddled and needs clearer coding.

But, I am having tenant and life complications, so do not hold your breath.

Lar.

f_mrcleansmalm_77ce002.jpgAutoIt has helped make me wealthy

Link to comment
Share on other sites

That's excellent Larry. Can't get it to work on my computer yet though.

I made a script to send files to a remote computer using the TCP functions. What I did was use a script (passthru) to convert the file to a string. The problem was that the string is huge and it took ages to send, so I was only able to send small files. Bigger files would get corrupted.

I don't have my script here, but you can imagine how it works. Here's paullab's passthru: http://www.autoitscript.com/forum/index.php?showtopic=31450

Edited by Nahuel
Link to comment
Share on other sites

Had some problems editting Post #1 ... anyway, updated to fix corrupt binary data... Seems to work great now... turns out I needed to cast TCPRecv'd data to Binary() ... I was assuming that TCPRecv would automagically know I sent Binary data...

Lar.

f_mrcleansmalm_77ce002.jpgAutoIt has helped make me wealthy

Link to comment
Share on other sites

When i run the server and then 2 clients, and then when i close the client i runned first the server shutsdown and i get the error:

C:\Documents and Settings\#####\Desktop\server.au3 (226) : ==> Array variable has incorrect number of subscripts or subscript dimension range exceeded.:

$party[$partyAnimal][0] = $party[$partyAnimal+1][0]

$party[$partyAnimal][0] = ^ ERROR

->10:05:16 AutoIT3.exe ended.rc:1

it's in this fuction:

Func SomeoneLeftTheParty($partyPooper)
    Local $partyAnimal
   
    TCPCloseSocket($party[$partyAnimal][0])
   
    If Not ($partyPooper = $party[0][0]) Then
        For $partyAnimal = $partyPooper To $party[0][0]
            $party[$partyAnimal][0] = $party[$partyAnimal+1][0]
            $party[$partyAnimal][1] = $party[$partyAnimal+1][1]
            $party[$partyAnimal][2] = $party[$partyAnimal+1][2]
        Next
    EndIf
    Redim $party[$party[0][0]][4]
    $party[0][0] -= 1
    
EndFunc

is this a bug or am i doing something wrong?

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...