Jump to content

TCP Made Easy


themax90
 Share

Recommended Posts

I don't know if this matters, or if it changes anything about TCP commands, but I made a "Newbie Friendly" version of TCP. TCP should already be "Newbie Friendly" but perhaps since I broke this down they can understand a bit more about the TCP Native Commands. The only USEFUL functions are TCPStartServer and TCPStopServer, but I made the other functions just for fun.

I ONLY TRULY RECOMMEND TCPStartServer!!!

These functions were made to explain TCP as a scripter would understand because sometimes Helpfiles can be misleading to patrons of different languages.

TCP Funcs.au3

#include-once
; ----------------------------------------------------------------------------
; AutoIt Version: 3.1.1.92
; Author:        Max Gardner <AutoIt Smith;king.of.all@comcast.net>
; ----------------------------------------------------------------------------
; ----------------------------------------------------------------------------
; Function: TCPStartServer($Port[, $MaxConnection])
;   $Port = Port To Start Server On
;   $MaxConnection = (Optional) Maximum Connections Allowed; Default 1
;   
; Returns:
;   Success : Returns Socket and @Error = 0
;   Failure : Returns 0 or 1 and sets @Error to Windows API WSAGetLasterror
;          0 = TCP Services Not Avialible On That Port
;          -1 = TCP Services Would Not StartUp              
; ----------------------------------------------------------------------------
Func TCPStartServer($Port, $MaxConnect = 1)
    Local $Socket
    $Socket = TCPStartup()
    Select
    Case $Socket = 0
        SetError(@Error)
        Return -1
    EndSelect
    $Socket = TCPListen(@IpAddress1, $Port, $MaxConnect)
    Select
    Case $Socket = -1
        SetError(@Error)
        Return 0
    EndSelect
    SetError(0)
    Return $Socket
EndFunc
; ----------------------------------------------------------------------------
; Function: TCPAllowConnection($Socket)
;   $Socket = The Main Socket As Returned By TCPStartServer
;   
; Returns:
;   Success : Returns ConnectedSocket and @Error = 0
;   Failure : Returns -1 and sets @Error to Windows API WSAGetLasterror         
; ----------------------------------------------------------------------------
Func TCPAllowConnection($Socket)
    Local $ConnectedSocket
    $ConnectedSocket = TCPAccept($Socket)
    Select
    Case $ConnectedSocket >= 0
        SetError(0)
        Return $ConnectedSocket
    Case Else
        SetError(@Error)
        Return -1
    EndSelect
EndFunc
; ----------------------------------------------------------------------------
; Function: TCPReceive($ConnectedSocket, $MaxChar)
;   $ConnectedSocket = The Connected Socket As Returned By TCPAllowConnection
;   
; Returns:
;   Success : Returns Recieved String and @Error = 0
;   Failure : Returns -1 and sets @Error to Windows API WSAGetLasterror         
; ----------------------------------------------------------------------------
Func TCPReceive($ConnectedSocket, $MaxChar = 512)
    Local $Data
    $Data = TCPRecv($ConnectedSocket, $MaxChar)
    Select
    Case $Data = ""
        SetError(@Error)
        Return -1
    Case Else
        SetError(0)
        Return $Data
    EndSelect
EndFunc
; ----------------------------------------------------------------------------
; Function: TCPSendMessage($ConnectedSocket, $String)
;   $ConnectedSocket = The Connected Socket As Returned By TCPAllowConnection
;   $String = Data to be sent
;   
; Returns:
;   Success : Returns 1 and @Error = 0
;   Failure : Returns -1 or 0 and sets @Error to Windows API WSAGetLasterror
;   
; ----------------------------------------------------------------------------
Func TCPSendMessage($ConnectedSocket, $String)
    Local $Sent
    $Sent = TCPSend($ConnectedSocket, $String)
    Select
    Case $Sent = 0
        SetError(@Error)
        Return -1
    Case Else
        SetError(0)
        Return 1
    EndSelect
EndFunc
; ----------------------------------------------------------------------------
; Function: TCPStopServer($MainSocket, $ConnectedSocket)
;   $MainSocket = The Socket As Returned By TCPStartServer
;   $ConnectedSocket = The Connected Socket As Returned By TCPAllowConnection
;   
; Returns:
;   Success : Returns 1 and @Error = 0
;   Failure : Returns -1 and sets @Error to Windows API WSAGetLasterror
;          0 = Unable To Shutdown TCP Services
;         -1 = Unable To Close Socket/s
; ----------------------------------------------------------------------------
Func TCPStopServer($MainSocket, $ConnectedSocket)
    Local $Shutdown
    Select
    Case $ConnectedSocket <> -1 
        $ConnectedSocket = TCPCloseSocket($ConnectedSocket)
        Select
        Case $ConnectedSocket = 0
            SetError(@Error)
            Return -1
        EndSelect
    EndSelect
    Select
    Case $MainSocket <> -1
        $MainSocket = TCPCloseSocket($MainSocket)
        Select
        Case $MainSocket = 0
            SetError(@Error)
            Return -1
        EndSelect
    EndSelect
    $Shutdown = TCPShutdown()
    Select
    Case $Shutdown = 0
        SetError(@Error)
        Return 0
    EndSelect
    SetError(0)
    Return 1
EndFunc

Here is an example of how it would work server side.

#include <Misc.au3>
#include 'TCP Funcs.au3'
Local $ConnectedSocket = -1
$MainSocket  = TCPStartServer(7000)
While _IsPressed('1B') = 0
    If $ConnectedSocket = -1 Then $ConnectedSocket = TCPAllowConnection($MainSocket)
    $Data = TCPReceive($ConnectedSocket)
    If @Error = 0 Then MsgBox(0, "Message Received", $Data)
    Sleep(100)
WEnd
TCPStopServer($MainSocket, $ConnectedSocket)

As you see it reduces the entire amount of code you need for TCP services from about 70 to around 10ish :P.

Here is a sample sender that you can use to test the example

#include 'TCP Funcs.au3'
TCPStartup()
$Socket = TCPConnect("71.56.132.184", 7000)
TCPSendMessage($Socket, "This is a test!")
TCPCloseSocket($Socket)
TCPShutdown()

I hope you like it!

AutoIt Smith

Edited by AutoIt Smith
Link to comment
Share on other sites

  • 1 year later...

Only recieves one message. Thought because it is looping I should beable to send message 1 then message 2 and so on. Has to be restarted every time. How can I make it recieve multiple messages without restart ove reciever/server ?

Link to comment
Share on other sites

Way to bump a 2 year old post.

Link to comment
Share on other sites

  • 3 months later...

I tried this. But it is not working :)

tcplisten is success (retrieves a socket)

tcpaccept results in -1

so rest also (allowconnection -1, tcpreceive also.

When running, My msgbox is flashing -1

Even my tcpsendmessage results in a return 0 (failure)

Why is this?

I've been trying to get something like this to work for a whole day now. But keep getting thos damn -1 returns.

Link to comment
Share on other sites

  • 4 weeks later...

Sorry to bring back an old post but i was wonder on how i could use this same server/client code but beable to have more connections. All data being sent would be the same. It would help alot in managing my network.

Link to comment
Share on other sites

Sorry to bring back an old post but i was wonder on how i could use this same server/client code but beable to have more connections. All data being sent would be the same. It would help alot in managing my network.

Check out other topics by AutoItSmith. The concept is quite simple, you have an array in which all socket information is stored. When someone new connects, you place the socket number into that array, and when he disconnects you remove him from the array.

Link to comment
Share on other sites

Yes, the connection limit is only that of autoits array parameter. It does slow down drastically with very high volumes, but that issue has been addressed in ITS 1.0(TBA) - but thats simply because autoit doesn't have the ability to do more then one thing at a single time.

Wow, this is a hella old post, I havn't even programmed in like a year!

Link to comment
Share on other sites

  • 6 months later...

Server has this:

#include 'TCP Funcs.au3'
Local $ConnectedSocket = -1
$MainSocket  = TCPStartServer(7000)
While 1
    If $ConnectedSocket = -1 Then $ConnectedSocket = TCPAllowConnection($MainSocket)
    $Data = TCPReceive($ConnectedSocket)
    If @Error = 0 Then MsgBox(0, "Message Received", $Data)
    Sleep(100)
WEnd
TCPStopServer($MainSocket, $ConnectedSocket)oÝ÷ Ø)bz{a²Øb±«­¢+Ø¥¹±Õ±Ðí5¥Í¹ÔÌÐì(¥¹±ÕÌäíQ
@չ̹ÔÌÌäì)¡½Ñ­åÍÐ ÌäíÌäì°Ìäí}ÑÍÐÌäì¤()Ý¡¥±Ä(ͱÀ ÄÀÀ¤)]¹()Õ¹}ÑÍÐ ¤(Q
AMÑÉÑÕÀ ¤(ÀÌØíM½­ÐôQ
A
½¹¹Ð¡%AÉÍÌÄ°ÜÀÀÀ¤(Q
AM¹5ÍÍ ÀÌØíM½­Ð°ÅÕ½ÐíQ¡¥Ì¥ÌÑÍÐÌÌìÅÕ½Ðì¤(Q
A
±½ÍM½­Ð ÀÌØíM½­Ð¤(Q
AM¡Õѽݸ ¤)¹Õ¹

How comes only one message is received by the server? I mean, the first time I press 'a', the message (= This is a test!) is sent to the server, which shows it nicely inside a messagebox, however when I press 'a' again, nothing happens.

Edited by Sven
Link to comment
Share on other sites

#include 'TCP Funcs.au3'
Local $ConnectedSocket = -1
$MainSocket  = TCPStartServer(7000)
While 1
    If $ConnectedSocket = -1 Then $ConnectedSocket = TCPAllowConnection($MainSocket)
    $Data = TCPReceive($ConnectedSocket)
    If @Error = 0 Then 
         MsgBox(0, "Message Received", $Data)
    Else
         $ConnectedSocket = -1
    EndIf
    Sleep(100)
WEnd
TCPStopServer($MainSocket, $ConnectedSocket)

Link to comment
Share on other sites

Thank you for your input, greatly appreciated. However, when using your suggestions for both server and client, whenever the client connects to the server, the server keeps spawning '-1' messageboxes. When the hotkey is pressed, server shows the correct message, but then reverts back to looping '-1' messages. Unfortunately I'm unable to figure out why or how to get rid of the -1s. Trying to intercept the -1 messages results in no messageboxes shown at all, even when the right one should appear.

Oh, and thank you for the fix for the client. TCPConnect takes quite alot of time, so anything that reduces its use is very welcome.

Edited by Sven
Link to comment
Share on other sites

I hope that this helps. It doesn't require any includes.

Server:

Dim $iMainSocket = 0
Dim $iConnectedSocket = -1
Dim $sData = ""

TCPStartup() ; Initialize the TCP functions/library

$iMainSocket = TCPListen(@IPAddress1,7000) ; Create a listening socket

While 1
    If $iConnectedSocket >= 0 Then ; We have a connection
        
        $sData = TCPRecv($iConnectedSocket,1024) ; Receive data up 
        
        If @error Then ; The client has closed the connection. Reset $iConnectedSocket so that we may listen for new connections.
            
            $iConnectedSocket = -1
            ConsoleWrite("Client has disconnected" & @CRLF)
            
        ElseIf $sData Then ; There has been some data sent.
            
            MsgBox(0, "Message Received", $sData)
            
        EndIf
        
    Else ; We do not have a connection, try to accept an incoming connection
        
        $iConnectedSocket = TCPAccept($iMainSocket) ; The connection is made, in the next loop that follows it will try to receive data,
                                                    ; If the connection is not made, the next loop will try to accept an incoming connection.
        If $iConnectedSocket >= 0 Then
            ConsoleWrite("Connection established" & @CRLF)
        EndIf
    EndIf

Wend
Link to comment
Share on other sites

An idea for you guys to consider is to add a Endmessage character or something.

If you have:

TCPSend($Sock, "Message1")

TCPSend($Sock, "Message2")

and the server lags a little bit or is parsing out messages you can get: Message1Message2

Link to comment
Share on other sites

Thanks a lot!

Finally a way for my scripts to communicate :D

Just having one small problem:

Sending data back from the server to the client...

Anyone having an idea how to run a server script on SERVER, which is always listening for incoming connections,

and a client script on PC (behind NAT), which connects outwards through a NAT to SERVER.

Once the connection is established they both have to set some "connection established" token, and enable other scripts to send data in two directions over this connection...

Is that possible?

Thanks!

Link to comment
Share on other sites

Thanks a lot!

Finally a way for my scripts to communicate :D

Just having one small problem:

Sending data back from the server to the client...

Anyone having an idea how to run a server script on SERVER, which is always listening for incoming connections,

and a client script on PC (behind NAT), which connects outwards through a NAT to SERVER.

Once the connection is established they both have to set some "connection established" token, and enable other scripts to send data in two directions over this connection...

Is that possible?

Thanks!

Ok, I just want to say before we start off. This is not "Finally a way for your scripts to community". The functions to do it have been around for almost 2 whole years. xD But I don't blame you for not knowing.

It doesn't matter if the client is behind a NAT, because NAT only involves incoming connections and not outgoing.

The connection established token you are talking about is automatically handled by AutoIt and TCP.

Other then that, just try any of the scripts above.

Link to comment
Share on other sites

I still have no clue how to send messages to the client from the server. I always seem to get it wrong. :D Even after looking at other people's scripts... :D

[left][sub]We're trapped in the belly of this horrible machine.[/sub][sup]And the machine is bleeding to death...[/sup][sup][/sup][/left]

Link to comment
Share on other sites

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