Buchempfehlung
Windows System Programming
Windows System Programming
Das Kompendium liefert viele interessante Informationen zur Windows-Programmierung auf Englisch. [Mehr Infos...]
FreeBASIC-Chat
Es sind Benutzer im FreeBASIC-Chat online.
(Stand:  )
FreeBASIC bei Twitter
Twitter FreeBASIC-Nachrichten jetzt auch über Twitter erhalten. Follow us!

fb:porticula NoPaste

Info
Info / Hilfe
Liste
Übersicht / Liste
Neu
Datei hochladen
Suche
Quellcode suchen
Download
Dateidownload

PNE :: include/pne/pne.mod.client.bi

Uploader:MitgliedPMedia
Datum/Zeit:05.12.2007 15:07:34

''==============================================================================
Type client
    writBuffM As Any Ptr
    readbuffM As Any Ptr
    writBuff  As String
    readBuff  As String
    wbuffl:1  As Ubyte
    rbuffl:1  As Ubyte
    versionS  As String                = versionString
    dnsname   As Uinteger
    ip        As Uinteger
    port      As Uinteger
    lasterror As Uinteger
    socket    As Socket
    connected As Ubyte
    mode      As Ubyte                 = mode_tcp

    async_handlr As Any Ptr
    async_reader As Any Ptr
    async_writer As Any Ptr

    ahand_exit:1 As Ubyte
    aread_exit:1 As Ubyte
    awrit_exit:1 As Ubyte

    datainbuffer:1 As Ubyte

    onReceive As Sub(Text As String)
    onError As Sub()
    onDisconnect As Sub()
    onConnect As Sub()

    Declare Function ResolveDNS(dnsname As String) As Uinteger

    Declare Sub connectdns(dnsname As String, port As Uinteger)
    Declare Sub connectips(ip As String, port As Uinteger)
    Declare Sub connectipi(ip As Uinteger, port As Uinteger)
    Declare Sub connect()

    Declare Sub lock_writebuffer()
    Declare Sub lock_readbuffer()

    Declare Sub unlock_writebuffer()
    Declare Sub unlock_readbuffer()

    Declare Sub writeNL( text As String )
    Declare Sub writeLN( ln   As String )

    Declare Sub Read( Byref Text As String)
    Declare Sub readln( Byref text As String)
    Declare Sub readUntilDCon( Byref text As String )

    Declare Sub bindEvent( Event As Uinteger, Adress As Any Ptr)
    Declare Sub setmode ( mode As Uinteger)
    Declare Function GetLastError( LangCode As String = "EN" ) As String

    Declare Sub disconnect()

    Declare Constructor
    Declare Destructor

End Type

''==============================================================================
Declare Sub AsyncEventhandler(cdata As client Ptr)
Declare Sub AsyncWriter(cdata As client Ptr)
Declare Sub AsyncReader(cdata As client Ptr)

''------------------------------------------------------------------------------
Sub AsyncEventhandler(cdata As client Ptr)
    Dim tempstr As String
    Dim LastErr As Integer
    Dim LastState As Integer
    Do
        Sleep 5
        If (cdata->connected = 1) Then
            If (cdata->datainbuffer = 1) Then
                If (cdata->onReceive <> 0) Then
                    cdata->Read(TempStr)
                    cdata->onReceive(TempStr)
                End If
            End If
        End If
        If (lasterr <> cdata->lasterror) Then
            lasterr = cdata->lasterror
            If (cdata->onError <> 0) Then
                cdata->onError()
            End If
        End If
        If (laststate <> cdata->connected) Then
            laststate = cdata->connected
            If (cdata->connected = 0) Then
                If (cdata->onDisconnect <> 0) Then
                    cdata->onDisconnect()
                End If
            End If
            If (cdata->connected = 1) Then
                If (cdata->onConnect <> 0) Then
                    cdata->onConnect()
                End If
            End If
        End If
    Loop Until cdata->ahand_exit = 1
End Sub

Sub AsyncWriter(cdata As client Ptr)
    dim si as sockaddr_in
    Do
        Sleep 5
        If (cdata->connected = 1) Then
            Mutexlock cdata->writbuffm
            If (Len(cdata->writbuff) <> 0) Then
                If (cdata->mode = mode_tcp) Then
                    If (send( cdata->socket, cdata->writbuff, Len( cdata->writbuff ), 0 ) = SOCKET_ERROR) Then
                        cdata->lasterror = WRITE_FAILED
                    Else
                        cdata->writbuff = ""
                    End If
                elseif (cdata->mode = mode_udp) then
                    si.sin_family = AF_INET
                    si.sin_port = htons(cdata->port)
                    if (sendto(cdata->socket, cast( ZSTRING PTR, @cdata->writbuff), len( cdata->writbuff ), 0, cast(sockaddr ptr, @si), len(si))) Then
                        cdata->lasterror = WRITE_FAILED
                    Else
                        cdata->writbuff = ""
                    End If
                End If
            End If
            Mutexunlock cdata->writbuffm
        End If
    Loop Until cdata->awrit_exit = 1
End Sub

Sub AsyncReader(cdata As client Ptr)
    Dim temps As Zstring * readbufflen
    Dim bytes As Integer
    Do
        Sleep 5
        If (cdata->connected = 1) Then
            If (cdata->mode = mode_tcp) Then
                Mutexlock cdata->readbuffm
                temps = ""
                bytes = 0
                bytes = recv( cdata->socket, temps, READBUFFLEN, 0 )
                If( bytes <= 0 ) Then
                    cdata->connected = 0
                Else
                    temps[bytes] = 0
                    cdata->readbuff += temps
                    cdata->datainbuffer = 1
                End If
                Mutexunlock cdata->readbuffm
            End If
        End If
    Loop Until cdata->aread_exit = 1

End Sub

''==============================================================================

Constructor client ()
Dim Adress As Any Ptr
this.writbuffm = Mutexcreate
this.readbuffm = Mutexcreate

this.async_handlr = Threadcreate(cast(Any Ptr, @AsyncEventhandler), @this)
this.async_reader = Threadcreate(cast(Any Ptr, @AsyncWriter), @this)
this.async_writer = Threadcreate(cast(Any Ptr, @AsyncReader), @this)

End Constructor

Destructor client ()
this.disconnect()

this.ahand_exit=1
this.aread_exit=1
this.awrit_exit=1

Threadwait(this.async_handlr)
Threadwait(this.async_reader)
Threadwait(this.async_writer)

Mutexdestroy this.writbuffm
Mutexdestroy this.readbuffm
End Destructor

''==============================================================================

Function client.resolveDNS(dnsname As String) As Uinteger
    Dim ia As in_addr
    Dim hostentry As hostent Ptr
    Dim IP As Uinteger
    ia.S_addr = inet_addr( dnsname )
    If ( ia.S_addr = INADDR_NONE ) Then
        hostentry = gethostbyname( dnsname )
        If ( hostentry = 0 ) Then
            this.lasterror = RESOLVE_HOSTNOTFOUND
        Else
            IP = *cast( Uinteger Ptr, *hostentry->h_addr_list )
        End If
    Else
        IP = ia.S_addr
    End If
    Return IP
End Function

Sub client.connectdns(dnsname As String, port As Uinteger)
    If (this.connected = 0) Then
        this.ip = this.resolveDNS(dnsname)
        this.port = port
        this.connect()
    Else
        this.lasterror = CONNECT_ALREADYCONNECTED
    End If
End Sub

Sub client.connectips(ip As String, port As Uinteger)
    If (this.connected = 0) Then
        this.ip = this.resolveDNS(ip)
        this.port = port
        this.connect()
    Else
        this.lasterror = CONNECT_ALREADYCONNECTED
    End If
End Sub

Sub client.connectipi(ip As Uinteger, port As Uinteger)
    If (this.connected = 0) Then
        this.ip = ip
        this.port = port
        this.connect()
    Else
        this.lasterror = CONNECT_ALREADYCONNECTED
    End If
End Sub

Sub client.connect()
    Dim sa As sockaddr_in
    If (this.connected = 0) Then
        If (this.ip <> 0) Then
            If (this.mode = mode_tcp) Then
                this.socket = opensocket( AF_INET, SOCK_STREAM, IPPROTO_TCP )
                If (this.socket <> 0) Then
                    sa.sin_port         = htons( this.port )
                    sa.sin_family       = AF_INET
                    sa.sin_addr.S_addr  = this.ip
                    If ( connect_( this.socket, cast( PSOCKADDR, @sa ), Len( sa )) = SOCKET_ERROR ) Then
                        this.lasterror = CONNECT_FAILED
                        closesocket( this.socket )
                        this.connected = 0
                    Else
                        this.connected = 1
                    End If
                Else
                    this.lasterror = OPENSOCKET_FAILED
                End If
            Elseif (this.mode = mode_udp) Then
                this.socket = opensocket( AF_INET, SOCK_DGRAM, IPPROTO_UDP )
                If (this.socket <> 0) Then
                    sa.sin_family = AF_INET
                    sa.sin_port = htons(this.port)
                    if (bind(this.socket, cast(sockaddr ptr, @sa), sizeof(sa))=-1) then
                        this.lasterror = BIND_FAILED
                    else
                        this.connected = 1
                    end if
                Else
                    this.lasterror = OPENSOCKET_FAILED
                End If
            End If


        Else
            this.lasterror = CONNECT_HOSTNOTFOUND
        End If
    Else
        this.lasterror = CONNECT_ALREADYCONNECTED
    End If
End Sub

Sub client.lock_writebuffer()
    this.wbuffl = 1
End Sub

Sub client.unlock_writebuffer()
    this.wbuffl = 0
End Sub

Sub client.lock_readbuffer()
    this.rbuffl = 1
End Sub

Sub client.unlock_readbuffer()
    this.rbuffl = 0
End Sub

Sub client.writeNL( ln   As String )
    Mutexlock this.writbuffm
    this.writbuff += ln
    Mutexunlock this.writbuffm
End Sub

Sub client.writeLN( ln   As String )
    Mutexlock this.writbuffm
    this.writbuff += ln + NEWLINE
    Mutexunlock this.writbuffm
End Sub

Sub client.Disconnect
    If (this.connected = 1) Then
        closesocket( this.socket )
        this.connected = 0
    End If
End Sub

Sub client.read(Byref text As String)
    Mutexlock this.readbuffm
    text = this.readbuff
    this.readbuff = ""
    datainbuffer = 0
    Mutexunlock this.readbuffm
End Sub

Sub client.readuntildcon(Byref text As String)
    Dim temp As String
    text = ""
    Do
        this.read(temp)
        text += temp
        Sleep 5
    Loop Until this.connected = 0
End Sub

Sub client.bindEvent( Event As Uinteger, Adress As Any Ptr)
    Select Case Event
    Case e_onNewClient
        this.lasterror      = NON_MATCHING_EVENTCODE
    Case e_onClientLost
        this.lasterror      = NON_MATCHING_EVENTCODE
    Case e_onReceive
        this.onReceive      = Adress
    Case e_onError
        this.onError        = Adress
    Case e_onConnect
        this.onConnect      = Adress
    Case e_onDisconnect
        this.onDisconnect   = Adress
    Case Else
        this.lasterror      = UNKOWN_EVENTCODE
    End Select

End Sub

Function client.GetLastError( LangCode As String = "EN" ) As String

    Select Case LangCode
    Case Else
        Select Case this.lasterror
        Case NO_ERR
            Return "No Error"
        Case CONNECT_HOSTNOTFOUND
            Return "Failed to establish connection: Host not found"
        Case CONNECT_FAILED
            Return "Connection failed"
        Case CONNECT_ALREADYCONNECTED
            Return "Could not create new connection: you're already connected"
        Case OPENSOCKET_FAILED
            Return "OpenSocket() failed. Please check your local system librarys and socket support"
        Case READ_FAILED
            Return "recv() failed"
        Case RESOLVE_HOSTNOTFOUND
            Return "Could not resolve host"
        Case WRITE_FAILED
            Return "Could not write data to destination"
        Case UNKOWN_EVENTCODE
            Return "BindEvent() failed: unkown eventcode."
        Case NON_MATCHING_EVENTCODE
            Return "You're using an eventcode that doesn't work with this class."
        Case UNKOWN_MODE
            Return "You're using an unkown transfer-mode."
        case BIND_FAILED
            Return "Bind() failed"
        Case Else
            Return "Unkown Error"
        End Select
    End Select

End Function

Sub client.setmode ( mode As Uinteger)
    If (this.connected = 0) Then
        Select Case mode
        Case mode_tcp
            this.mode = mode_tcp
        Case Else
            this.lasterror = UNKOWN_MODE
        End Select
    Else
        this.lasterror = CONNECT_ALREADYCONNECTED
    End If
End Sub