fb:porticula NoPaste
PNE :: include/pne/pne.mod.client.bi
Uploader: | PMedia |
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