 |
Das deutsche QBasic- und FreeBASIC-Forum Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
|
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
arduno
Anmeldungsdatum: 12.05.2011 Beiträge: 252
|
Verfasst am: 24.02.2012, 10:56 Titel: Wie funktioniert das mit diesem Server-Client-Programm ? |
|
|
Eigentlich ist die funktionsweise gegeben. Es kommt die Meldung : "Nun mit 1 Verbunden" und darunter "Suche Server".
Mein Client hier funktioniert und hat Verbindung aufgenommen mit dem Zusi-Server Portnr: 1435.
Es können auch Daten übertragen werden vom Cienten zum Zusi-Server und es kommen anschliessend dauerhaft Daten vom Zusi-Server zurück, wie es ein soll.
Aber mit den Meldungen oben komme ich nicht ganz klar.
Evtl die erste Meldung verstehe ich noch , das die Verbindung zum Zusi-Server besteht, aber die 2. Meldung verstehe ich nicht, was die aussagt, es funktioniert doch eigentlich das was ich möchte.
Es müsste doch die Meldung kommen : "Server bereit", wenn mein Client die Verbindung zum Zusi-TCP(Server) aufgenommen hat.
Oder sehe ich das etwas falsch ?
Oder wird hier automatisch noch ein Server zusätzlich eingerichtet.
Wenn ja, wie kann ich das unterbinden ?
Gruss
Code: |
#Include Once "TSNE_V3.bi"
Screen 19,32
Dim Shared As Integer partnerID, zaehler,geschw,mdrehz
Dim Shared As String sBuffer
Dim Shared As Single bremsdr
Type connectionType
As UInteger G_Server, G_Client
As Integer isServer
As String IP
Declare Constructor(Typ As String)
Declare Destructor
Declare Sub hosten
Declare Sub connecten
Declare Sub beenden
Declare Sub senden(Message As String)
End Type
'Subs für TSNE-Kommunikation
Declare Sub TSNE_Disconnected(ByVal V_TSNEID as UInteger)
Declare Sub TSNE_Connected(ByVal V_TSNEID as UInteger)
Declare Sub TSNE_NewData(ByVal V_TSNEID as UInteger, ByRef V_Data as String)
Declare Sub TSNE_NewConnection(ByVal V_TSNEID as UInteger, ByVal V_RequestID as Socket, ByVal V_IPA as String)
Declare Sub TSNE_NewConnectionCanceled(ByVal V_TSNEID as UInteger, ByVal V_IPA as String)
Constructor connectionType(Typ As String)
If Typ = "Server" Then
isServer = 1
hosten
ElseIf Typ = "Client" Then
IP = "127.0.0.2"
connecten
Else
IP = Typ
connecten
EndIf
End Constructor
Destructor connectionType
beenden
End Destructor
Sub connectionType.beenden
If isServer Then
TSNE_Disconnect(G_Server) 'Server beenden
TSNE_WaitClose(G_Server) 'Warten bis Server beendet ist
Else
TSNE_Disconnect(G_Client) 'Client beenden
TSNE_WaitClose(G_Client) 'Warten bis Client beendet ist
EndIf
End Sub
Sub connectionType.hosten
Dim BV As Integer
BV = TSNE_Create_Server(G_Server, 1436, 1, @TSNE_NewConnection, @TSNE_NewConnectionCanceled) 'Server erstellen
If BV = TSNE_Const_NoError Then
Print "Server bereit"
Else
Print "Fehler: " & BV
EndIf
End Sub
Sub connectionType.connecten
Dim BV As Integer
BV = TSNE_Create_Client(G_Client, IP, 1435, @TSNE_Disconnected, @TSNE_Connected, @TSNE_NewData) 'Client erstellen
If BV = TSNE_Const_NoError Then
Print "Suche Server"
Else
Print "Fehler: " & BV
EndIf
End Sub
Sub connectionType.senden(Message As String)
TSNE_Data_Send(partnerID, Message)
End Sub
Sub TSNE_Disconnected(ByVal V_TSNEID as UInteger)
'Handling, wenn disconnected wird
Print V_TSNEID & " wurde disconnectet"
End Sub
Sub TSNE_Connected(ByVal V_TSNEID as UInteger)
'neue Verbindung wurde aufgebaut
Print "Nun mit " & V_TSNEID & " verbunden"
partnerID = V_TSNEID
End Sub
Sub TSNE_NewConnection(ByVal V_TSNEID as UInteger, ByVal V_RequestID as Socket, ByVal V_IPA as String)
'Wenn versucht wird, eine neue Verbindung herzustellen
'Nur wichtig für den Server
Print "Ein Client versucht zu verbinden"
Dim XNewTSNEID as UInteger
Dim XReturnIPA as String
'Akzeptieren der Verbindung
TSNE_Create_Accept(V_RequestID, XNewTSNEID, XReturnIPA, @TSNE_Disconnected, @TSNE_Connected, @TSNE_NewData)
End Sub
Sub TSNE_NewConnectionCanceled(ByVal V_TSNEID as UInteger, ByVal V_IPA as String)
'Verhalten, wenn abgelehnt wird
Print "Verbindung wurde abgelehnt"
End Sub
Sub TSNE_NewData(ByVal V_TSNEID as UInteger, ByRef V_Data as String)
If len(V_Data) > 8 Then
For zaehler=7 To len(V_Data) Step 5
if asc(Mid(V_Data,zaehler,1))= 1 Then
geschw=Int(Cvs(Mid(V_Data,zaehler+1,4))+0.5)
ElseIf asc(Mid(V_Data,zaehler,1))= 2 Then
bremsdr=Cvs(Mid(V_Data,zaehler+1,4))
ElseIf asc(Mid(V_Data,zaehler,1))= 9 Then
mdrehz=Int(Cvs(Mid(V_Data,zaehler+1,4))+0.5)
EndIf
Locate 4,2
Print " "
Locate 4,2
Print geschw; mdrehz;" "; Using "#.#";bremsdr
Next
EndIf
End Sub
Dim As connectionType myClient = "Client"
sBuffer =CHR(&H0D)+CHR(0)+CHR(0)+CHR(0)+CHR(0)+CHR(1)+CHR(1)+CHR$(2)+Chr(8)+"Fahrpult"
myClient.senden(sBuffer)
Sleep 100
sBUFFER =CHR(&H07)+CHR(0)+CHR(0)+CHR(0)+CHR(0)+CHR(3)+CHR(0)+CHR(&H0A)+CHR(1)+chr(2)+Chr(9)
myClient.senden(sBuffer)
Sleep 100
sBUFFER =CHR(&H04)+CHR(0)+CHR(0)+CHR(0)+CHR(0)+CHR(3)+CHR(0)+Chr(0)
myClient.senden(sBuffer)
Sleep 100
Do
Sleep 50
Loop Until InKey = Chr(27)
myClient.beenden
|
|
|
Nach oben |
|
 |
RWK
Anmeldungsdatum: 04.07.2011 Beiträge: 44
|
Verfasst am: 24.02.2012, 11:58 Titel: |
|
|
Hoi,
du startest den Client :
da das TCP Packet angenommen wird gibt TSNE ein No_Error zurück also :
Code: | Print "Suche Server" |
die TSNE_connected Sub ist aber schneller also wird erstmal noch ausgegeben :
Code: | Print "Nun mit " & V_TSNEID & " verbunden" |
Server bereit kommt doch nur, wenn Du auch einen Server startest:
Code: | Sub connectionType.hosten
Dim BV As Integer
BV = TSNE_Create_Server(G_Server, 1436, 1, @TSNE_NewConnection, @TSNE_NewConnectionCanceled) 'Server erstellen
If BV = TSNE_Const_NoError Then
Print "Server bereit"
Else
Print "Fehler: " & BV
EndIf
End Sub |
ansonsten könnte 'Server bereit' ja nur über _NewData hereinkommen, so denn Dein externer Server sowas rausschicken würde
Grüße |
|
Nach oben |
|
 |
arduno
Anmeldungsdatum: 12.05.2011 Beiträge: 252
|
Verfasst am: 24.02.2012, 15:19 Titel: |
|
|
Jup, danke.
Gruss |
|
Nach oben |
|
 |
arduno
Anmeldungsdatum: 12.05.2011 Beiträge: 252
|
Verfasst am: 24.02.2012, 20:29 Titel: |
|
|
Hmm.., das Programm schmiert nach ca 3 Minuten ab, bzw blockiert. Ich stelle die Daten : Geschindigkeit,Motordrehzahl und Bremsdruck grafisch dar.
Ist das zuviel in dieser Abfrage-Sub :
Sub TSNE_NewData(ByVal V_TSNEID as UInteger, ByRef V_Data as String)
Code: |
#Include Once "TSNE_V3.bi"
#include once "fbgfx.bi"
#include once "vbcompat.bi"
#include once "rotation6-4.bas"
Dim Shared As Single x_t,y_t,x_m,y_m,x_b,y_b,scale
Dim Shared As Integer dst_hb,dst_hb2
Dim Shared As fb.image ptr zeig_t_scr_img
Dim Shared As fb.image ptr zeig_t_dst_img
Dim Shared As fb.image ptr kreis_t_img
Dim Shared As fb.image ptr zeig_m_scr_img
Dim Shared As fb.image ptr zeig_m_dst_img
Dim Shared As fb.image ptr kreis_m_img
Dim Shared As fb.image ptr zeig_b_scr_img
Dim Shared As fb.image ptr zeig_b_dst_img
Dim Shared As fb.image ptr kreis_b_img
Dim Shared As Integer partnerID, zaehler,geschw,mdrehz
Dim Shared As String sBuffer
Dim Shared As Single bremsdr
Declare Sub TSNE_Disconnected(ByVal V_TSNEID as UInteger)
Declare Sub TSNE_Connected(ByVal V_TSNEID as UInteger)
Declare Sub TSNE_NewData(ByVal V_TSNEID as UInteger, ByRef V_Data as String)
Declare Sub TSNE_NewConnection(ByVal V_TSNEID as UInteger, ByVal V_RequestID as Socket, ByVal V_IPA as String)
Declare Sub TSNE_NewConnectionCanceled(ByVal V_TSNEID as UInteger, ByVal V_IPA as String)
Const As single pi = 3.1415926, pi_180 = pi / 180
screenres 300,750,32
Type connectionType
As UInteger G_Server, G_Client
As Integer isServer
As String IP
Declare Constructor(Typ As String)
Declare Destructor
Declare Sub hosten
Declare Sub connecten
Declare Sub beenden
Declare Sub senden(Message As String)
End Type
Constructor connectionType(Typ As String)
If Typ = "Server" Then
isServer = 1
hosten
ElseIf Typ = "Client" Then
IP = "127.0.0.1"
connecten
Else
IP = Typ
connecten
EndIf
End Constructor
Destructor connectionType
beenden
End Destructor
Sub connectionType.beenden
If isServer Then
TSNE_Disconnect(G_Server) 'Server beenden
TSNE_WaitClose(G_Server) 'Warten bis Server beendet ist
Else
TSNE_Disconnect(G_Client) 'Client beenden
TSNE_WaitClose(G_Client) 'Warten bis Client beendet ist
EndIf
End Sub
Sub connectionType.hosten
Dim BV As Integer
BV = TSNE_Create_Server(G_Server, 9000, 1, @TSNE_NewConnection, @TSNE_NewConnectionCanceled) 'Server erstellen
If BV = TSNE_Const_NoError Then
Print "Server bereit"
Else
Print "Fehler: " & BV
EndIf
End Sub
Sub connectionType.connecten
Dim BV As Integer
BV = TSNE_Create_Client(G_Client, IP, 1435, @TSNE_Disconnected, @TSNE_Connected, @TSNE_NewData) 'Client erstellen
If BV = TSNE_Const_NoError Then
'Print "Suche Server"
Else
Print "Fehler: " & BV
EndIf
End Sub
Sub connectionType.senden(Message As String)
TSNE_Data_Send(partnerID, Message)
End Sub
Sub TSNE_Disconnected(ByVal V_TSNEID as UInteger)
'Handling, wenn disconnected wird
Print V_TSNEID & " wurde disconnectet"
End Sub
Sub TSNE_Connected(ByVal V_TSNEID as UInteger)
'neue Verbindung wurde aufgebaut
Print "Nun mit " & V_TSNEID & " verbunden"
partnerID = V_TSNEID
End Sub
Sub TSNE_NewConnection(ByVal V_TSNEID as UInteger, ByVal V_RequestID as Socket, ByVal V_IPA as String)
'Wenn versucht wird, eine neue Verbindung herzustellen
'Nur wichtig für den Server
Print "Ein Client versucht zu verbinden"
Dim XNewTSNEID as UInteger
Dim XReturnIPA as String
'Akzeptieren der Verbindung
TSNE_Create_Accept(V_RequestID, XNewTSNEID, XReturnIPA, @TSNE_Disconnected, @TSNE_Connected, @TSNE_NewData)
End Sub
Sub TSNE_NewConnectionCanceled(ByVal V_TSNEID as UInteger, ByVal V_IPA as String)
'Verhalten, wenn abgelehnt wird
Print "Verbindung wurde abgelehnt"
End Sub
Sub TSNE_NewData(ByVal V_TSNEID as UInteger, ByRef V_Data as String)
If len(V_Data) > 8 Then
For zaehler=7 To len(V_Data) Step 5
if asc(Mid(V_Data,zaehler,1))= 1 Then
geschw=Int(Cvs(Mid(V_Data,zaehler+1,4))+0.5)+45
ElseIf asc(Mid(V_Data,zaehler,1))= 2 Then
bremsdr=Cvs(Mid(V_Data,zaehler+1,4))*30+45
ElseIf asc(Mid(V_Data,zaehler,1))= 9 Then
mdrehz=Int(Cvs(Mid(V_Data,zaehler+1,4))+0.5)/10
EndIf
ScreenLock
Put (x_t,y_t),kreis_t_img,trans
RotateScale(zeig_t_dst_img,zeig_t_scr_img,dst_hb/2,dst_hb/2,geschw,scale)
Put (x_t,y_t),zeig_t_dst_img,Trans
Put (x_m,y_m),kreis_m_img,trans
RotateScale(zeig_m_dst_img,zeig_m_scr_img,dst_hb/2,dst_hb/2,mdrehz,scale)
Put (x_m,y_m),zeig_m_dst_img,Trans
Put (x_b,y_b),kreis_b_img,trans
RotateScale(zeig_b_dst_img,zeig_b_scr_img,dst_hb/2,dst_hb/2,bremsdr,scale)
Put (x_b,y_b),zeig_b_dst_img,Trans
ScreenUnLock
Next
EndIf
End Sub
dst_hb=150*1.5
dst_hb2=dst_hb/2
zeig_t_dst_img = imagecreate(dst_hb,dst_hb,RGB(255,0,255))
zeig_t_scr_img = imagecreate(150,150,RGB(255,0,255))
kreis_t_img=imagecreate(dst_hb,dst_hb,RGB(255,0,255))
Circle kreis_t_img,(dst_hb2,dst_hb2),100,RGB(50,50,50),,,,f
Line zeig_t_scr_img,(75,75)-(75,150),RGB(255,0,0)
Line zeig_t_scr_img,(73,75)-(77,130),RGB(255,0,0),bf
zeig_m_dst_img = imagecreate(dst_hb,dst_hb,RGB(255,0,255))
zeig_m_scr_img = imagecreate(150,150,RGB(255,0,255))
kreis_m_img=imagecreate(dst_hb,dst_hb,RGB(255,0,255))
Circle kreis_m_img,(dst_hb2,dst_hb2),100,RGB(50,50,50),,,,f
Line zeig_m_scr_img,(75,75)-(75,150),RGB(0,255,0)
Line zeig_m_scr_img,(73,75)-(77,130),RGB(0,255,0),bf
zeig_b_dst_img = imagecreate(dst_hb,dst_hb,RGB(255,0,255))
zeig_b_scr_img = imagecreate(150,150,RGB(255,0,255))
kreis_b_img=imagecreate(dst_hb,dst_hb,RGB(255,0,255))
Circle kreis_b_img,(dst_hb2,dst_hb2),100,RGB(50,50,50),,,,f
Line zeig_b_scr_img,(75,75)-(75,150),RGB(0,0,255)
Line zeig_b_scr_img,(73,75)-(77,130),RGB(0,0,255),bf
scale=1.0
x_t=10
y_t=50
x_m=10
y_m=270
x_b=10
y_b=490
Dim As connectionType myClient = "Client"
sBuffer =CHR(&H0D)+CHR(0)+CHR(0)+CHR(0)+CHR(0)+CHR(1)+CHR(1)+CHR$(2)+Chr(8)+"Fahrpult"
myClient.senden(sBuffer)
Sleep 100
sBUFFER =CHR(&H07)+CHR(0)+CHR(0)+CHR(0)+CHR(0)+CHR(3)+CHR(0)+CHR(&H0A)+CHR(1)+chr(2)+Chr(9)
myClient.senden(sBuffer)
Sleep 100
sBUFFER =CHR(&H04)+CHR(0)+CHR(0)+CHR(0)+CHR(0)+CHR(3)+CHR(0)+Chr(0)
myClient.senden(sBuffer)
Sleep 100
Do
If multikey(fb.sc_escape) then
End
End If
Sleep 5
Loop
myClient.beenden
|
|
|
Nach oben |
|
 |
nemored

Anmeldungsdatum: 22.02.2007 Beiträge: 4704 Wohnort: ~/
|
Verfasst am: 24.02.2012, 23:40 Titel: |
|
|
Code: | asc(Mid(V_Data,zaehler,1))= 2 |
kannst du optimieren zu
Code: | V_Data[zaehler-1]= 2 |
(nur wenn V_Data lang genug ist).
Das war aber nicht deine Frage. Ich vermute stark, dass dir ein Multithreading-Konflikt in den Weg kommt. Du sperrst in der Funktion ja den Bildschirmzugriff. Wenn währenddessen erneut die Funktion aufgerufen wird, will dieser zweite Aufruf ebenfalls sperren, und das gibt Probleme. Du solltest für den Bereich lieber ein Mutex anlegen. _________________ Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1. |
|
Nach oben |
|
 |
arduno
Anmeldungsdatum: 12.05.2011 Beiträge: 252
|
Verfasst am: 25.02.2012, 11:00 Titel: |
|
|
Danke.
Hmm..., wie sieht denn ein "Mutex" in meinem Programm aus.
Davon verstehe ich jetzt überhaupt nichts.
Gruss |
|
Nach oben |
|
 |
nemored

Anmeldungsdatum: 22.02.2007 Beiträge: 4704 Wohnort: ~/
|
Verfasst am: 25.02.2012, 12:21 Titel: |
|
|
Lies dir mal den Referenzartikel durch und schau dir das beigelegte Beispiel gut an. Außerdem empfehle ich das Tutorial im Forum. Mutexe sind zu komplex, als dass ich sie mal eben so schnell erklären könnte - jedenfalls nicht besser als es die Referenz und das Tutorial tut. _________________ Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1. |
|
Nach oben |
|
 |
ThePuppetMaster

Anmeldungsdatum: 18.02.2007 Beiträge: 1839 Wohnort: [JN58JR]
|
Verfasst am: 25.02.2012, 12:58 Titel: |
|
|
TSNE_ ruft für >eine< verbindugn alle Callbacks seriell auf. Sprich. Wenn daten für die verbindung z.B. 17 eingehen, wird die sub new_data aufgerufen. sollte wärend der arbeit erneut daten eintreffen, wird solange gewartet, bis diese funktion fertig ist. erst dann wird die funktion erneut aufgerufen. gleiches gilt auch für connect / disconnect. Sprich, wenn eine dieser 3 funktionen aufgerufen wurde, wird solange gewartet, bis diese fertig ist, bevor eine andere oder dieselbe noch einmal aufgerufen wird.
auch bei mehreren verbindugnen wird dieses vorgehen so verwendet. der einzigste unterschied ist, das mehrere verbindungen parallel arbeiten können. aber die seriealität dieser 3 funktionen für jede verbindung für sich bleibt erhalten.
Das Problem, das dir dieses app zerlegt liegt an Screenlock/unlock und dem multikey.
Diese beiden Befehle laufen in 2 seperaten Threads. Thread 1 ist deine Do-Loop schleife am ende, wo auch multikey verwendung findet. Das ist der Haupt-thread der anwendung. Dieser ist immer vorhanden.
der 2. thread wird hier durch tsne erzeugt. Und zwar beim aufruf von TSNE_Create_xxx
Dies ist nötig, damit die verbindung autonom arbeiten kann, udn auch mehrere verbindungen gleichzeitig arbeiten können.
Durch diesen 2. thread werden automatisch (wenn nötig) die callbacks (disconnect / connect / new_data) aufgerufen.
Das bedeutet, das jetzt 2 Threads gleichzeitig arbeiten und jeweils unterschiedliche dinge tuen können.
Das Problem ist hierbei jedcoh, das einige FreeBASIC befehle damit nicht zurecht kommen, bzw (wie man es auch ausdrückt) "nicht threadsafe" sind.
Hier muss man von "hand" dafür sorgen, das mehrere Threads, nicht gleichzeitig auf 2 funktionen zugreifen können.
In deinem Fall ist dies Screenlock und Multikey. Diese beiden sidn nicht Threadsafe (genauso wie alle anderen Grafikbefehle wie line, put, pixel, usw. .
Um dies zu schützen kannst du ein Mutex erzeugen
Code: |
Dim shared TMutex as Any Ptr
TMutex = MutexCreate()
|
Die Mutex-Nummer wird hier in TMutex gespeichert.
Es ist quasi eine Spezielle-Variable die im Betriebssystem verankert ist.
Jetzt kannst du mit diesem Mutex eine Sperrung ausführen:
Code: |
MutexLock(TMutex)
If MultiKey(fb.sc_escape) Then
mutexunlock(TMutex)
end
end if
mutexunlock(tmutex)
sleep 5
|
Wichtig ist, das man nach dem zugriff auf die entsprechende zu schützende Funktion das Mutex auch wieder entsperrt.
Gleiches muss man jetzt auch "um das screenlock herum" ausführen
Code: |
mutexlock(tmutex)
screenlock()
'...
screenunlock()
mutexunlock(tmutex)
|
Vergleichbar ist dieses vorgehen mit folgenden funktionen (Representativ)
Code: |
Sub MyMutexLock(V_Mutex as Any Ptr)
do
if *v_mutex = 0 then
*v_mutex = 1
exit sub
end if
loop
End Sub
|
bzw.
Code: |
Sub MyMutexUnLock(V_Mutex as Any Ptr)
*v_mutex = 0
End Sub
|
Im grunde tut mutexlock nur solange warten, bis das mutex einen bestimmten wert besitzt (in meinem beispiel 0). erst wenn das der fall ist, wird das mutex gesperrt (1) und die funktion verlassen. Das programm kann weiter arbeiten.
Nachdem alles fertig ist, entspeert man das mutex wieder (unlock=0)
sollte zwischenzeitlich eine andere funktion das mutexlock aufrufen, ist diese variable auf 1. daher muss solange die schleife durchlaufen werden, bis das mutex wieder auf 0 steht (was die andere funktion nach seiner arbeit natürlich per unlock auch zurücksetzt)
usw.
MfG
TPM _________________ [ WebFBC ][ OPS ][ ToOFlo ][ Wiemann.TV ] |
|
Nach oben |
|
 |
arduno
Anmeldungsdatum: 12.05.2011 Beiträge: 252
|
Verfasst am: 25.02.2012, 14:24 Titel: |
|
|
Jup, danke.
Gruss |
|
Nach oben |
|
 |
RWK
Anmeldungsdatum: 04.07.2011 Beiträge: 44
|
Verfasst am: 27.02.2012, 15:26 Titel: |
|
|
Ich hatte seinerzeit auch ein bissl Probleme mit der Verarbeitung in der CallBack Function. Ich bin dann einfach hergegangen und habe es ausgelagert. Dann gab es keine Probleme mehr.
Ich hab übrigens TSNE_Play benutzt....aber ist ja quasi nur ein TSNE Überbau.
Code: | Sub TSNEPlay_Message(ByVal V_FromPlayerID As UInteger, ByVal V_ToPlayerID As UInteger, ByVal V_Message As String, ByVal V_MessageType As TSNEPlay_MessageType_Enum)
Select Case V_MessageType
Case TSNEPlay_MSGType_Regular
checkMessage(V_FromPlayerID, V_Message)
Case TSNEPlay_MSGType_Private
Case TSNEPlay_MSGType_Notice
AddMessage (V_FromPlayerID, V_Message)
Case TSNEPlay_MSGType_Hightlighted
Case Else
End Select
End Sub |
|
|
Nach oben |
|
 |
arduno
Anmeldungsdatum: 12.05.2011 Beiträge: 252
|
Verfasst am: 27.02.2012, 16:13 Titel: |
|
|
Zitat: |
Ich bin dann einfach hergegangen und habe es ausgelagert.
|
Was hast du ausgelagert?
Gruss |
|
Nach oben |
|
 |
nemored

Anmeldungsdatum: 22.02.2007 Beiträge: 4704 Wohnort: ~/
|
Verfasst am: 27.02.2012, 17:32 Titel: |
|
|
Code: | checkMessage(V_FromPlayerID, V_Message) |
und
Code: | AddMessage(V_FromPlayerID, V_Message) |
Das Problem ist dann allerdings ebenfalls nur ausgelagert; die neuen SUBs müssen sich wiederum darum kümmern, dass es zu keinem Konflikt kommt. Zumindest kann ich mir nicht vorstellen, dass das Problem damit wirklich aus der Welt ist (aber meine Multithreading-Kenntnisse sind begrenzt ). _________________ Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1.
Zuletzt bearbeitet von nemored am 27.02.2012, 17:35, insgesamt einmal bearbeitet |
|
Nach oben |
|
 |
ThePuppetMaster

Anmeldungsdatum: 18.02.2007 Beiträge: 1839 Wohnort: [JN58JR]
|
Verfasst am: 27.02.2012, 17:34 Titel: |
|
|
richtig.
auserdem erhöht eine weitere sub die auslastung des Thread-Stacks.
Wenn möglich sollte man solche vermeiden. Ansonsten kann es zu probleme kommen. Hier müsste man (wenn der stack nicht ausreichen würde), via V_StackOverrideSize Parameter einen größeren Stacksize angeben.
MfG
TPM _________________ [ WebFBC ][ OPS ][ ToOFlo ][ Wiemann.TV ] |
|
Nach oben |
|
 |
RWK
Anmeldungsdatum: 04.07.2011 Beiträge: 44
|
Verfasst am: 27.02.2012, 17:56 Titel: |
|
|
na dass :
Code: | Sub TSNE_NewData(ByVal V_TSNEID as UInteger, ByRef V_Data as String)
If len(V_Data) > 8 Then
For zaehler=7 To len(V_Data) Step 5
if asc(Mid(V_Data,zaehler,1))= 1 Then
geschw=Int(Cvs(Mid(V_Data,zaehler+1,4))+0.5)
ElseIf asc(Mid(V_Data,zaehler,1))= 2 Then
bremsdr=Cvs(Mid(V_Data,zaehler+1,4))
ElseIf asc(Mid(V_Data,zaehler,1))= 9 Then
mdrehz=Int(Cvs(Mid(V_Data,zaehler+1,4))+0.5)
EndIf
Locate 4,2
Print " "
Locate 4,2
Print geschw; mdrehz;" "; Using "#.#";bremsdr
Next
EndIf
End Sub |
zu sowas ungefähr:
Code: | Sub TSNE_NewData(ByVal V_TSNEID as UInteger, ByRef V_Data as String)
checkData(V_Data)
End Sub
Sub checkData( incomingData as string)
static V_Data as string
V_Data += incomingData
If len(V_Data) > 8 Then
For zaehler=7 To len(V_Data) Step 5
if asc(Mid(V_Data,zaehler,1))= 1 Then
geschw=Int(Cvs(Mid(V_Data,zaehler+1,4))+0.5)+45
ElseIf asc(Mid(V_Data,zaehler,1))= 2 Then
bremsdr=Cvs(Mid(V_Data,zaehler+1,4))*30+45
ElseIf asc(Mid(V_Data,zaehler,1))= 9 Then
mdrehz=Int(Cvs(Mid(V_Data,zaehler+1,4))+0.5)/10
EndIf
ScreenLock
Put (x_t,y_t),kreis_t_img,trans
RotateScale(zeig_t_dst_img,zeig_t_scr_img,dst_hb/2,dst_hb/2,geschw,scale)
Put (x_t,y_t),zeig_t_dst_img,Trans
Put (x_m,y_m),kreis_m_img,trans
RotateScale(zeig_m_dst_img,zeig_m_scr_img,dst_hb/2,dst_hb/2,mdrehz,scale)
Put (x_m,y_m),zeig_m_dst_img,Trans
Put (x_b,y_b),kreis_b_img,trans
RotateScale(zeig_b_dst_img,zeig_b_scr_img,dst_hb/2,dst_hb/2,bremsdr,scale)
Put (x_b,y_b),zeig_b_dst_img,Trans
ScreenUnLock
Next
EndIf
end sub
|
klar muss man aufpassen, dass der Code sich nicht überholt, aber das bringt man schon hin. Zur Not muss die Malanzeige halt in einem eigenen Thread laufen. Dann wäre auch eine individuelle Anzeigeintervall Steuerung ohne Probleme möglich.
Und beim Datastring vorne immer schön abschneiden, was schon verarbeitet wurde  |
|
Nach oben |
|
 |
arduno
Anmeldungsdatum: 12.05.2011 Beiträge: 252
|
Verfasst am: 18.03.2012, 10:45 Titel: |
|
|
Muss die mutexlock hier auch vor jeden einzelnen Grafikbefehl gesetzt werden?
Gruss
Code: |
mutexlock(tmutex)
ScreenLock
Put (x_t,y_t),kreis_t_img,trans
RotateScale(zeig_t_dst_img,zeig_t_scr_img,dst_hb/2,dst_hb/2,geschw,scale)
Put (x_t,y_t),zeig_t_dst_img,Trans
Put (x_m,y_m),kreis_m_img,trans
RotateScale(zeig_m_dst_img,zeig_m_scr_img,dst_hb/2,dst_hb/2,mdrehz,scale)
Put (x_m,y_m),zeig_m_dst_img,Trans
Put (x_b,y_b),kreis_b_img,trans
RotateScale(zeig_b_dst_img,zeig_b_scr_img,dst_hb/2,dst_hb/2,bremsdr,scale)
Put (x_b,y_b),zeig_b_dst_img,Trans
ScreenUnLock
mutexunlock(tmutex)
|
|
|
Nach oben |
|
 |
ThePuppetMaster

Anmeldungsdatum: 18.02.2007 Beiträge: 1839 Wohnort: [JN58JR]
|
Verfasst am: 18.03.2012, 10:50 Titel: |
|
|
nö ... du hast sie ja bereits "eingeklammert" ... oder nicht?
MfG
TPM _________________ [ WebFBC ][ OPS ][ ToOFlo ][ Wiemann.TV ] |
|
Nach oben |
|
 |
arduno
Anmeldungsdatum: 12.05.2011 Beiträge: 252
|
Verfasst am: 18.03.2012, 11:05 Titel: |
|
|
Diese Sub:
RotateScale(zeig_m_dst_img,zeig_m_scr_img,dst_hb/2,dst_hb/2,mdrehz,scale)
enhält ASM-Routinen, können die den Ablauf vom Server/Clienten stören ?
Oder kann auch ein Focuswechsel zwischen den Programmen auf dem Bildschirm störed sein für den Server/Clienten.
Die Ausfälle sind immer so nach ca 2 Minuten Datenübertragung da.
Den Fokus muss ich wechseln, weil das andere Programm auf Tastendruck gesteuert wird.
Gruss
Zuletzt bearbeitet von arduno am 18.03.2012, 11:08, insgesamt einmal bearbeitet |
|
Nach oben |
|
 |
ThePuppetMaster

Anmeldungsdatum: 18.02.2007 Beiträge: 1839 Wohnort: [JN58JR]
|
Verfasst am: 18.03.2012, 11:06 Titel: |
|
|
Wenn du mir erklärst, woher ich den Inhalt dieser Routine kennen soll, dann kann ich dir auch keine Antwort darauf geben.
MfG
TPM _________________ [ WebFBC ][ OPS ][ ToOFlo ][ Wiemann.TV ] |
|
Nach oben |
|
 |
arduno
Anmeldungsdatum: 12.05.2011 Beiträge: 252
|
Verfasst am: 18.03.2012, 11:09 Titel: |
|
|
Hier das Programm.
Wenn ich das rausnehme, läuft es.
Also muss hier im ASM-Code irgend etwas den Client durcheinander bringen.
Code: |
sub RotateScale( dst as FB.IMAGE ptr = 0, src as FB.IMAGE ptr, positx as integer, posity as integer, angle as single, SCALE as single )
#define PixSize uinteger
#define RegPix eax
const PI_180 = atn(1)/45
const cUSEBITS = 20
const cMULNUMB = 1 shl cUSEBITS
const cDIVNUMB = 1/cMULNUMB
const cBITREAL = (1 shl cUSEBITS)-1
const PixSz = sizeof(PixSize)
const PixMul = PixSz\2
static as byte INIT
static as any ptr STPTR
static as integer OLDPROT,BLKSZ
static as integer NX,NY,SX,SY
static as integer SW2, SH2, SWA,SHA
static as integer NXTC,NXTS,NYTC,NYTS,NXTCS,NXTSS
static as integer TC,TS,IMIN,IMAX
static as any ptr DSTPTR,SRCPTR
static as integer STARTX,STARTY,ENDX,ENDY,XPUT,YPUT
static as integer DSTWID,DSTHEI,DSTPIT,DSTEXT
' clearing access for selfmodify
'buffers info
dim as integer POSX=POSITX,POSY=POSITY
dim as integer SRCWID = src->width
dim as integer SRCHEI = src->height
dim as integer SRCPIT = src->pitch
dim as single ZOOMX = SCALE, ZOOMY = SCALE
if INIT=0 then
asm
inc dword ptr [INIT]
mov eax,offset _RTZ32_ASM_BEGIN_
mov ebx,offset _RTZ32_ASM_END_
mov [STPTR],eax
sub ebx,eax
mov [BLKSZ],ebx
end asm
VirtualProtect(STPTR,BLKSZ,PAGE_EXECUTE_READWRITE,@OLDPROT)
end if
if dst = 0 then
dstptr = screenptr
screeninfo DSTWID,DSTHEI
DSTPIT = DSTWID*sizeof(PixSize)
else
dstptr = cast( any ptr, dst+1):DSTPIT = dst->pitch
DSTWID = dst->width:DSTHEI = dst->height
end if
'quadrant
var DTMP = ANGLE
while DTMP < 0: DTMP += 360: wend
while DTMP > 360: DTMP -= 360: wend
while DTMP > 90: DTMP -= 90: wend
' rotation data
SRCPTR = cast( PixSize ptr, src+1)
SW2 = src->width\2: sh2 = src->height\2
TS = (sin( -angle * pi_180 )*cMULNUMB)/SCALE
TC = (cos( -angle * pi_180 )*cMULNUMB)/SCALE
if SH2 > SW2 then SWA = SH2 else SWA = SW2
SHA = (-int(-SWA*sin(PI_180*(DTMP+45))/sin(PI_180*45)))
SWA = (-int(-SWA*sin(PI_180*(DTMP+45))/sin(PI_180*45)))
'SHA=SH2*1.5:SWA=SW2*1.5
XPUT = SWA*ZOOMX-SW2: YPUT = SHA*ZOOMX-SH2
POSITX -= SW2: POSITY -= SH2
STARTX = -XPUT: ENDX = src->width+XPUT
STARTY = -YPUT: ENDY = src->height+YPUT
' clipping
IMIN = STARTX+POSITX: if IMIN < 0 then STARTX -= IMIN
IMAX = ENDX+POSITX: if IMAX >= DSTWID then ENDX += (DSTWID-1)-IMAX
if IMIN < 0 and IMAX < 0 then exit sub
if IMIN >= DSTWID and IMAX >= DSTWID then exit sub
IMIN = STARTY+POSITY: if IMIN < 0 then STARTY -= IMIN
IMAX = ENDY+POSITY: if IMAX >= DSTHEI then ENDY += (DSTHEI-1)-IMAX
if IMIN < 0 and IMAX < 0 then exit sub
if IMIN >= DSTHEI and IMAX >= DST then exit sub
' initial values
DSTPTR += (STARTY+POSITY)*DSTPIT
DSTPTR += (STARTX+POSITX)*sizeof(PixSize)
SX = (ENDX-STARTX)+1: SY = (ENDY-STARTY)+1
DSTEXT = DSTPIT-SX*sizeof(PixSize)
NY = (STARTY-SH2): NYTC = NY*TC: NYTS = NY*TS
NX = (STARTX-SW2): NXTCS = NX*TC: NXTSS = NX*TS
' self modifing variables to constants
asm
mov eax,[SX] 'SX
mov [_RTZ32_SX_CONST_1_-2],ax
mov eax,[SY] 'SY
mov [_RTZ32_SY_CONST_1_-4],eax
mov eax,[NXTCS] 'NXTCS
mov [_RTZ32_NXTCS_CONST_1_-4],eax
mov eax,[NXTSS] 'NXTSS
mov [_RTZ32_NXTSS_CONST_1_-4],eax
mov eax,[SW2] 'SW2
mov [_RTZ32_SW2_CONST_1_-4],eax
mov eax,[SH2] 'SH2
mov [_RTZ32_SH2_CONST_1_-4],eax
mov eax,[SRCWID] 'SRCWID
mov [_RTZ32_SRCWID_CONST_1_-4],eax
mov eax,[SRCHEI] 'SRCHEI
mov [_RTZ32_SRCHEI_CONST_1_-4],eax
mov eax,[SRCPTR] 'SRCPTR
mov [_RTZ32_SRCPTR_CONST_1_-4],eax
mov eax,[SRCPIT] 'SRCPIT
mov [_RTZ32_SRCPIT_CONST_1_-4],eax
mov eax,[DSTEXT] 'DSTEXT
mov [_RTZ32_DSTEXT_CONST_1_-4],eax
mov eax,[TC] 'TC
mov [_RTZ32_TC_CONST_1_-4],eax
mov [_RTZ32_TC_CONST_2_-4],eax
mov eax,[TS] 'TS
mov [_RTZ32_TS_CONST_1_-4],eax
mov [_RTZ32_TS_CONST_2_-4],eax
end asm
#ifdef __FB_WIN32__
FlushInstructionCache(GetCurrentProcess(),STPTR,BLKSZ)
#endif
' draw rotated/scaled block
asm
#define SelfMod 0x8899AABB
#define SelfMod16 0x88BB
#define _DSTPTR_ edi
#define _PY_ ecx
#define _PX_ cx
#define _NXTC_ ebx
#define _NXTS_ edx
#define _NYTS_ esp
#define _NYTC_ ebp
_RTZ32_ASM_BEGIN_: '\
mov _DSTPTR_,[DSTPTR] '|
mov eax,[NYTS] '|
mov ebx,[NYTC] '| Rotate/zoom
movd mm0,ebp '| asm begin
movd mm1,esp '|
mov _NYTS_,eax '|
mov _NYTC_,ebx '/
mov _PY_,SelfMod '\
_RTZ32_SY_CONST_1_: '|
shl _PY_,16 '| for PY = SX to 1 step-1
.balign 8 '|
_BEGIN_FOR_PY_: '/
mov _NXTC_,SelfMod '\ NXTC=NXTCS: NXTS = NXTSS
_RTZ32_NXTCS_CONST_1_: '|
sub _NXTC_,_NYTS_ '|
mov _NXTS_,SelfMod '|
_RTZ32_NXTSS_CONST_1_: '|
add _NXTS_,_NYTC_ '/
mov _PX_,SelfMod16 '\ for PX = SY to 1 step-1
_RTZ32_SX_CONST_1_: '|
.balign 8 '|
_BEGIN_FOR_PX_: '/
'mov byte ptr [_DSTPTR_],255
mov esi,_NXTC_ '\
sar esi,cUSEBITS '| MX = ((NXTC-NYTS) shr cUSEBITS) + SW2
adc esi,SelfMod '|
_RTZ32_SW2_CONST_1_: '/
js _SKIP_IF_1_ '\
cmp esi,SelfMod '| if MX>=0 and MX<SRCWID then
_RTZ32_SRCWID_CONST_1_: '|
jge _SKIP_IF_1_ '|
shl esi,PixMul '\
add esi,SelfMod '| OFFS = MX+SRCPTR
_RTZ32_SRCPTR_CONST_1_: '/
mov eax,_NXTS_ '\
sar eax, cUSEBITS '| MY = ((NYTC+NXTS) shr cUSEBITS) + SH2
adc eax, SelfMod '|
_RTZ32_SH2_CONST_1_: '/
js _SKIP_IF_1_ '\
cmp eax,SelfMod '| if MY>=0 and MY<SRCHEI then
_RTZ32_SRCHEI_CONST_1_: '|
jge _SKIP_IF_1_ '/
imul eax,SelfMod '\
_RTZ32_SRCPIT_CONST_1_: '|
add esi,eax '| col = *cast(PixSize ptr, SRCPTR+MY*SRCPIT+MX)
mov RegPix,[esi] '/
'or al,al '\ 'if col<>RGB(255,0,255) then
'jz _SKIP_IF_1_ '/
mov [_DSTPTR_],RegPix '> *cast(PixSize ptr, DSTPTR) = COL
.balign 2 '> end if
_SKIP_IF_1_: '/ end if:end if
add _DSTPTR_,PixSz 'DSTPTR += sizeof(PixSize)
add _NXTC_,SelfMod '\ NXTC += TC: NXTS += TS
_RTZ32_TC_CONST_1_: '|
add _NXTS_,SelfMod '|
_RTZ32_TS_CONST_1_: '/
dec _PX_ '\ next PX
jnz _BEGIN_FOR_PX_ '/
add _DSTPTR_,SelfMod '\ DSTPTR += DSTEXT
_RTZ32_DSTEXT_CONST_1_: '/
add _NYTC_,SelfMod '\
_RTZ32_TC_CONST_2_: '|NYTC += TC: NYTS += TS
add _NYTS_,SelfMod '|
_RTZ32_TS_CONST_2_: '/
sub _PY_,(1 shl 16) '\ next PY
jnz _BEGIN_FOR_PY_ '/
movd ebp,mm0 '\
movd esp,mm1 '| Rotate/Zoom
emms '| Asm End
_RTZ32_ASM_END_: '/
end asm
end sub
|
|
|
Nach oben |
|
 |
arduno
Anmeldungsdatum: 12.05.2011 Beiträge: 252
|
Verfasst am: 20.03.2012, 10:46 Titel: |
|
|
Hmmm.,.. liegt es an den Grafikbefehlen ?
Auch dieses MUTEX nützt nichts.
Gruss |
|
Nach oben |
|
 |
|
|
Du kannst keine Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum nicht antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen.
|
|