Sign in to follow this  
Followers 0
gigi1

Couple of TCP problems

6 posts in this topic

hi, i've been testing TCP today, i also wrote a server, and i found some problems client-side:

1) in this code, if i delete the sleep(100) from line 14, it does send TCP message over LAN, but not over the internet (both if i use the external IP from my local machine, or having it run from another machine over the internet).

interestingly enough, the client does not return any error, it connects to the server, but it sends nothing.

TCPStartup()

Global $IpAddress=TCPNameToIP("blablabla.no-ip.biz")
Global $Port = 2123

If _TCPSend("just some text") = 0 Then MsgBox(0, "error", "<.<")

TCPShutdown()

Func _TCPSend($fdata)
    $TCPConnect = TCPConnect($IpAddress, $Port)
    If $TCPConnect = -1 Then Return 0
    Sleep(100)  ;without this it doesn't work - idk why
    TCPSend($TCPConnect, $fdata)
    Return 1
EndFunc

2) i've tryed with a friend, and it seems that the function TCPNameToIP("<name>") doesnt work sometimes. we tryed quite a few times with exactly the same client and server under different circumstances, and that function causes the client not to connect. all that i changed was:

Global $IpAddress=TCPNameToIP("blablabla.no-ip.biz")

to

Global $IpAddress= "xxx.xxx.xxx.xxx"

(my ip address instead of those xxx, obviously)

my questions are:

-is it supposed to behave like that?

-is there a problem in the code, or maybe in network configuration, or somewhere else?

-is there something i can do to remove that sleep(100)?

P.S.: i can provide the code of my server if you think it could help

thanks in advance

gigi1

Share this post


Link to post
Share on other sites



In both cases, (TCPNameToIP and TCPConnect) try detecting errors using @error (see the examples in TCPSend in the help file) instead of the return value (as in question 1) or nothing (as in question 2). Subsequent calls to TCP functions would fail if those do...

Share this post


Link to post
Share on other sites

ok, but why does those functions fail? and the TCPNameToIP is at the beginning of the script, there's no way it detects an @error

(i'm not sure i fully understood your answer - sorry i'm not english)

Share this post


Link to post
Share on other sites

For TCPNameToIP to work properly you need to have internet connection. That function is a wrapper for some other (winsock) function, and that other function connects to remote server ,DNS server, collecting data from there. The protocol is standardized and specification can be found on the internet, naturally. It's about getting the A record for specific domain. One of my first scripts in AutoIt was communication with DNS server to get specific MX records. I just checked the folder with scripts I wrote and found one for A record too. It's this:

Global $sDomain = "dikydee.dyndns.org" ; change it to domain of your interest

ConsoleWrite(_DNS_GetARecords($sDomain) & @CRLF)

;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Func _DNS_GetARecords($sDomain)
    Local $bBinary = _DNS_QueryAServer($sDomain)
    If @error Then Return SetError(1, 0, "")
    Local $aOut = _DNS_ExtractAData($bBinary)
    If @error Then Return SetError(2, 0, "")
    Return $aOut
EndFunc   ;==>_DNS_GetARecords

Func _DNS_QueryAServer($sDomain)
    Local $aDomain = StringSplit($sDomain, ".", 3)
    Local $sQueryDomain
    For $i = 0 To UBound($aDomain) - 1
        $sQueryDomain &= Hex(BinaryLen($aDomain[$i]), 2) & Hex(Binary($aDomain[$i]))
    Next
    Local $iIdentifier = Hex(Random(0, 255, 1), 2)
    ; Construct the query following the specification of the protocol for A record
    Local $bQuery = Binary("0x00" & $iIdentifier & "01000001000000000000" & $sQueryDomain & "0000010001") ; this is the query
    Local $aSocket, $bRcvData
    UDPStartup()
    For $iRound = 1 To 9
        Local $sServer
        Switch $iRound
            Case 1
                $sServer = "8.8.4.4"
            Case 2
                $sServer = "4.2.2.3"
            Case 3
                $sServer = "8.8.8.8"
            Case 4
                $sServer = "4.2.2.4"
            Case 5
                $sServer = "208.67.222.222"
            Case 6
                $sServer = "208.67.220.220"
            Case 7
                $sServer = "4.2.2.5"
            Case 8
                $sServer = "4.2.2.6"
            Case 9
                Return SetError(1, 0, "")
        EndSwitch
        If $sServer Then
            $aSocket = UDPOpen($sServer, 53)
            If @error Or $aSocket[0] = -1 Then
                UDPCloseSocket($aSocket)
                ContinueLoop
            EndIf
            UDPSend($aSocket, $bQuery)
            For $i = 1 To 5
                $bRcvData = UDPRecv($aSocket, 512, 1)
                If $bRcvData Then ExitLoop
                Sleep(100)
            Next
            If $bRcvData And Hex(BinaryMid($bRcvData, 2, 1)) = $iIdentifier Then
                UDPShutdown()
                Return $bRcvData
            EndIf
        EndIf
    Next
    UDPShutdown()
    Return SetError(2, 0, "")
EndFunc   ;==>_DNS_QueryAServer

Func _DNS_ExtractAData($bBinary)
    Local $aAnswers = StringSplit($bBinary, "C00C00010001", 1)
    If UBound($aAnswers) > 1 Then
        Local $bData = BinaryMid($bBinary, 6 + BinaryLen($aAnswers[1]) + 6)
        Local $tARaw = DllStructCreate("byte[" & BinaryLen($bData) & "]")
        DllStructSetData($tARaw, 1, $bData)
        Local $tAData = DllStructCreate("byte DataLength; byte IP[4];", DllStructGetPtr($tARaw))
        Return DllStructGetData($tAData, "IP", 1) & "." & DllStructGetData($tAData, "IP", 2) & "." & DllStructGetData($tAData, "IP", 3) & "." & DllStructGetData($tAData, "IP", 4)
    EndIf
    Return SetError(1, 0, "")
EndFunc   ;==>_DNS_ExtractAData

It will show you what TCPNameToIP() is and why it fails when it fails and if it fails.

Hope that helps.


♡♡♡

.

eMyvnE

Share this post


Link to post
Share on other sites

ok, but why does those functions fail? and the TCPNameToIP is at the beginning of the script, there's no way it detects an @error

There's a lot of reasons why they COULD fail, detecting the error code can help you troubleshoot your specific problem:

TCPStartup()

Global $IpAddress=TCPNameToIP("blablabla.no-ip.biz")
if (@error) Then
    MsgBox(0,"TCPNameToIP Error","Code: "&@error)
    Exit
EndIf
Global $Port = 2123

If _TCPSend("just some text") = 0 Then MsgBox(0, "error", "<.<")

TCPShutdown()

Func _TCPSend($fdata)
    $TCPConnect = TCPConnect($IpAddress, $Port)
    if (@error) Then
        MsgBox(0,"TCPConnect Error","Code: "&@error)
        return 0
    EndIf
    TCPSend($TCPConnect, $fdata)
    if (@error) Then
        MsgBox(0,"TCPSend Error","Code: "&@error)
        return 0
    EndIf
    Return 1
EndFunc

If an error is given you can look up the code meaning on MSDN: http://msdn.microsoft.com/en-us/library/ms740668.aspx (note that TCPConnect codes 1 and 2 are proprietary).

Share this post


Link to post
Share on other sites

thanks for help, i figured out from MSDN that TCPNameToIp() needs TCPStartup() - i feel stupid :)

i'm filling my codes with error checks now :)

gigi1

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