Jump to content

Problem with TCP/IP


EFF
 Share

Recommended Posts

Im writing a simple client/server program. The client sends a text message to server, and the server displays it in the TextBox.

Server code:

$TcpStart = TCPStartup()
$TcpListen = TCPListen(@IPAddress1,120)

Dim $cUsers


#region  Okienko
; Script generated by AutoBuilder 0.5 Prototype

#include <GuiConstants.au3>

If Not IsDeclared('WS_CLIPSIBLINGS') Then Global $WS_CLIPSIBLINGS = 0x04000000

GuiCreate("EF notice server", 248, 81,(@DesktopWidth-248)/2, (@DesktopHeight-81)/2 , $WS_OVERLAPPEDWINDOW + $WS_VISIBLE + $WS_CLIPSIBLINGS)

$Input_1 = GuiCtrlCreateInput("", 20, 40, 180, 20)
$Label_2 = GuiCtrlCreateLabel("Wysłana wiadomość:", 20, 5, 150, 20)


GuiSetState()
While 1
    $pos = MouseGetPos()
    ToolTip("Server ON" & @CRLF & "Listening:" & @IPAddress1,$pos[0]+10,$pos[1])
    
    $TcpAccept = TCPAccept($TcpListen)
;If $TcpAccept >= 1 Then 
        
        $data  = TCPRecv($TcpAccept, 1024)
        If $data <> "" Then
            GUICtrlSetData(3,$data)
        EndIf
    
;EndIf
    
    $impulse  = GuiGetMsg()
    Select
    Case $impulse = $GUI_EVENT_CLOSE
        ExitLoop
    EndSelect
    Sleep(25)
WEnd
Exit
#endregion

    
$TcpShut = TCPShutdown()
$TcpClose = TCPCloseSocket()

============================

The code of the client is:

Opt("GUIOnEventMode",1)
#include <GUIConstants.au3>

$Form1 = GUICreate("Send a msg", 260, 66, 177, 117)
$Input1 = GUICtrlCreateInput("", 8, 16, 145, 21, -1, $WS_EX_CLIENTEDGE)
$Button1 = GUICtrlCreateButton("Wyślij", 168, 16, 49, 25)
$Button2 = GUICtrlCreateButton("X", 220, 16, 25, 25)
$Group1 = GUICtrlCreateGroup("AGroup1", 8, 0, 249, 65)
GUICtrlCreateGroup("", -99, -99, 1, 1)
GUISetState()

GUICtrlSetOnEvent($Button2,"quit")
GUISetOnEvent($GUI_EVENT_CLOSE,"quit")
GUICtrlSetOnEvent($Button1,"query")
;---Sieć
$TcpStart = TCPStartup()
global $host = TCPNameToIP("gpufury.hopto.org")
$TcpCon = TCPConnect($host,120)
If $TcpCon = -1 Then
        MsgBox(0,"Łączenie","Wystapił płąd podczas łączenia sie z serwerem(" & @error & ")")
    Exit
EndIf

While 1;Glowna petla
    Sleep(25)   
WEnd

Func query()
        $gMsg = GUICtrlRead($Input1)
        
        $TcpSend  = TCPSend($TcpCon,$gMsg)
        MsgBox(0,$gMsg,"Wysłano: "&$TcpSend& " bajtów")
        If $TcpSend = 0 Then
            MsgBox(0,"Błąd podczas wysyłania","Wystąpił błąd(" & @error & ")") 
        EndIf
        $TcpClose = TCPCloseSocket($TcpCon)
EndFunc
Func quit()
    Exit
EndFunc

global $TcpClose = TCPCloseSocket($TcpCon)
$TcpShut = TCPShutdown()

==================

And it doesnt work :P . I have rewritten the client code, so that it doesn`t have any gui, only TCP commands, and it works.

Code:

$TcpStart = TCPStartup()
$host = TCPNameToIP("gpufury.hopto.org")
$TcpCon = TCPConnect($host,120)
If $TcpCon = -1 Then
        MsgBox(0,"Łączenie","Wystapił płąd podczas łączenia sie z serwerem(" & @error & ")")
    Exit
EndIf

    $TcpSend  = TCPSend($TcpCon,"Test: Works")
    
    If $TcpSend = 0 Then
    MsgBox(0,"Error","(" & @error & ")")
    Exit
    EndIf


$TcpClose = TCPCloseSocket($TcpCon)
$TcpShut = TCPShutdown()

Exit

I suppose my error is in the client`s EventMode, but i cant find it.

Thanks for any help

Link to comment
Share on other sites

I will redirect you too my example TCP scripts. Study them so you can understand the structure a bit more.

http://www.autoitscript.com/forum/index.php?showtopic=19229

Scroll down a bit and I have these examples:

Server

Global $MainSocket = -1
Global $ConnectedSocket = -1
Local $MaxConnection = 1; Maximum Amount Of Concurrent Connections
Local $MaxLength = 512; Maximum Length Of String
Local $Port = 1000; Port Number
Local $Server = @IPAddress1; Server IpAddress
TCPStartup()
$MainSocket = TCPListen($Server, $Port)
If $MainSocket = -1 Then Exit MsgBox(16, "Error", "Unable to intialize socket.")
While 1
    $Data = TCPRecv($ConnectedSocket, $MaxLength)
    If $Data = "~bye" Then
        MsgBox(16, "Session Ended", "Connection Terminated.")
        Exit
    ElseIf $Data <> "" Then
 ; Unconditional Receive
        MsgBox(0, "Received Packet", $Data)
    EndIf
    If $ConnectedSocket = -1 Then
        $ConnectedSocket = TCPAccept($MainSocket)
        If $ConnectedSocket <> -1 Then
     ; Someone Connected
            TCPSend($ConnectedSocket, "Connected!")
        EndIf
    EndIf
WEnd
Func OnAutoItExit()
    If $ConnectedSocket <> - 1 Then
        TCPSend($ConnectedSocket, "~bye")
        TCPCloseSocket($ConnectedSocket)
    EndIf
    If $MainSocket <> -1 Then TCPCloseSocket($MainSocket)
    TCPShutdown()
EndFunc;==>OnAutoItExit

Client

Global $MainSocket
Local $MaxLength = 512; Maximum Length Of Text
Local $Port = 1000; Port Number
Local $Server = @IPAddress1; Server IpAddress
TCPStartup()
$MainSocket = TCPConnect($Server, $Port)
If $MainSocket = -1 Then Exit MsgBox(16, "Error", "Unable to connect.")
While 1
    $Data = TCPRecv($MainSocket, $MaxLength)
    If $Data = "~bye" Then
        MsgBox(16, "Session Ended", "Connection Terminated.")
        Exit
    ElseIf $Data <> "" Then
 ; Unconditional Receive
        MsgBox(0, "Received Packet", $Data)
    EndIf
WEnd
Func OnAutoItExit()
    If $MainSocket <> - 1 Then
        TCPSend($MainSocket, "~bye")
        TCPCloseSocket($MainSocket)
    EndIf
    TCPShutdown()
EndFunc;==>OnAutoItExit

As you can see, you can change it a bit too edit it into a GUI, just wrap the GUI code around it and you have it working. Also here is a multipul allowance structure.

http://www.autoitscript.com/forum/index.php?showtopic=19369

Global Const $Port = 50911
Global $MaxConc = 100
Global $MainSocket = TCPStartServer($Port, $MaxConc)
If @Error <> 0 Then Exit MsgBox(16, "Error", "Server unable to initialize.")
Global Const $MaxLength = 512
Global $ConnectedSocket[$MaxConc]
Global $CurrentSocket = 0
Local $Track = 0
Global Const $MaxConnection = ($MaxConc - 1)
For $Track = 0 To $MaxConnection Step 1
    $ConnectedSocket[$Track] = -1
Next
While 1
    $ConnectedSocket[$CurrentSocket] = TCPAccept($MainSocket)
    If $ConnectedSocket[$CurrentSocket] <> -1 Then
        $CurrentSocket = SocketSearch()
    EndIf
    $Track = 0
    For $Track = 0 To $MaxConnection Step 1
        If $ConnectedSocket[$Track] <> - 1 Then
            $Data = TCPRecv($ConnectedSocket[$Track], $MaxLength)
            If $Data = "~bye" Then
                TCPCloseSocket($ConnectedSocket[$Track])
                $ConnectedSocket[$Track] = -1
                $CurrentSocket = SocketSearch()
            ElseIf $Data <> "" Then
                TCPSendMessageAll($MaxConnection, $Data)
            EndIf
        EndIf
    Next
WEnd
Func TCPSendMessageAll($ConnectionLimit, $Data)
    Local $Track = 0
    For $Track = 0 To $ConnectionLimit Step 1
        If $ConnectedSocket[$Track] <> - 1 Then TCPSend($ConnectedSocket[$Track], $Data)
    Next
EndFunc;==>TCPSendMessageAll
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
Func SocketSearch()
    Local $Track = 0
    For $Track = 0 To $MaxConnection Step 1
        If $ConnectedSocket[$Track] = -1 Then
            Return $Track
        Else
     ; Socket In Use
        EndIf
    Next
EndFunc;==>SocketSearch

This can also be fitted with a simple GUI. If you need help contact me. Now, getting down too your script it self it seems too have a few fundemental flaws.

Server

1. Port Unreliablity

This can be caused by other programs interfacing previously on that port through TCP. For a list of TCP and UDP Ports go here:

http://www.iana.org/assignments/port-numbers

It seems port 120 is registered as this :

cfdptkt 120/tcp CFDPTKT

cfdptkt 120/udp CFDPTKT

# Owner: John Ioannidis <ji@close.cs.columbia.ed>

This may be one cause. Try going outside of the "Well-Known" port list, or if possible, try being in the "Dynamic and/or Private Ports" because they will have a higher chance of reliablity.

2. Imprecise Sockets

Your variables are a bit differenciated. They are not clear. For example, in the structured client, for every possible connection there is a variable for the socket. You have a single variable the accepts ALL connections and may be being overwritten. Try to prevent this by doing the following:

Global $TCPAccept = -1
; Later on in the script
If $TCPAccept = -1 Then 
   TCPAccept($TCPListen)
Else
; Another Connection Already Made
EndIf

3. TCPCloseSocket comes BEFORE TCPShutdown

You have it stated as this:

$TcpShut = TCPShutdown()
$TcpClose = TCPCloseSocket()

Which destroys the purpose of closing the socket because you have already shutdown TCP Services. It is more appropriate to have it as:

$TcpClose = TCPCloseSocket()
$TcpShut = TCPShutdown()

Also, you are NOT closing any sockets. You must give the defined socket to close it. For example:

If $TCPAccept <> -1 Then TCPCloseSocket($TCPAccept)
TCPCloseSocket($TCPListen)
TCPShutdown()

4. Improper Controls for GUI

You have the following GUISet error:

GUICtrlSetData(3,$data)

Because Controls change you assigned it too a variable in the beginning and should be set too that instead of numbers. It is unknown what "3" will ever do. Therefore it should now come out:

GUICtrlSetData($Label_2,$data)

However you are now loosing all of the data previously sent. So a quick adjustment will make it a bit more logical:

GUICtrlSetData($Label_2, GUICtrlRead($Label_2) & @CRLF & $data)

One thing I do notice is that you cannot send back messages as the server operator and you may want to look into that. The following project is based off of AutoIt's TCP functionality and you make want to look into it:

http://www.autoit-its.com/

I personally developed the Simple Client and Server.

I will check into your client code soon but it is a bit too jumbled too look through. Please run your scripts through http://www.autoitscript.com/fileman/users/jdeb/jdeb_autoit_stuff.htm before posting.

Edit 1: Checked your client code. It seems too be in order but abit illogical and hard too read. Do not forget too make things OnAutoItExit because when you exit with the button it does not close the socket and shutdown which may lead too a few errors. Likewise do this in your server. Although this is a good start, alot better then what I had when Larry first designed it with the DLLCall's. That was confusing! Anyways looking good. Just be a bit more precise and fix a few things, and it should work.

Best Wishes,

AutoIt Smith

Edited by AutoIt Smith
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...