Hehe,
thanks oncemore to netmaestro, so I could change my program to do the polling in different classrooms (see codes below), but the initial problem is still back:
I'd like to start all Clients with disabled buttons which get enabled only, when polling is started from the server. So I seem to need a broadcast which is seen from all clients...
My actual version works like that:
- Server is started on one PC
- Clients are started on different PCs, checking if a Server (in the ABCD.ini or Data.s) is present
- When Polling is started at the Server, the A-B-C-D entries (but only one of each client) is accepted and the result will be seen at the end.
Server
Code: Select all
Procedure Init()
EnableExplicit
#Pollzeit=300; Zehntelsekunden
#MehrfachAntworten=#False
#MaxSessions=100
Global Dim Sessions(#MaxSessions)
Global Dim Counter(4)
Global Dim Bingo(4)
Global Total
#ServerID=666
#ServerPort=6699
#Starttext="&Starte Wertung..."
#RandX=10
#RandY=25
#BarX=50
#BarY=280
#BarZ=10
#BildX=#RandX*2+#BarX*4+#Barz*3
#BildY=#RandY*2+#BarY
#WinRand=10
#WinUnten=81
#WinX=#BildX+#WinRand<<1
#WinY=#BildY+#WinRand+#WinUnten
Global ABCD
Global Event
Global ok
Global ClientID
Global ClientIP
Global Sekunden
Global dummy.s
Global i,j,x,y,quit
Global WinID
Global ImageID=CreateImage(0,#BildX,#BildY)
LoadFont(0,"Trebuchet MS",16)
LoadFont(1,"Trebuchet MS",10)
Enumeration 1
#Start
#Ende
#Bild
EndEnumeration
Enumeration
#IgnoriereNachrichten
#AkzeptiereNachrichten
EndEnumeration
Global Modus=#IgnoriereNachrichten
EndProcedure
Procedure.w Limit(low.w,med.w,high.w)
If med<low
ProcedureReturn low
ElseIf med>high
ProcedureReturn high
Else
ProcedureReturn med
EndIf
EndProcedure
Procedure Meldung(titel.s,meldung.s,icon=#IDI_ASTERISK,wait=30)
;#IDI_QUESTION ; (?)
;#IDI_HAND ; (X)
;#IDI_EXCLAMATION ; /!\
;#IDI_ASTERISK ; (i)
Define mouse.point
#Hoehe=64 ; mit Ok-Knopf: 96
GetCursorPos_(@mouse)
x=limit(0,(mouse\x)-130,GetSystemMetrics_(#SM_CXSCREEN)-260)
y=limit(0,(mouse\y)-100,GetSystemMetrics_(#SM_CYSCREEN)-#hoehe)
If OpenWindow(1,x,y,272,#hoehe,titel,#PB_Window_SystemMenu|#PB_Window_Invisible)
CreateGadgetList(WindowID(1))
ImageGadget(1, 12, 14, 0, 0, LoadIcon_(0,icon))
TextGadget(2,60,20,250,30,meldung)
DisableGadget(1,1)
HideWindow(1, 0)
quit=0
SetTimer_(WindowID(1),1,80,0) ; Default: 100ms
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow,#PB_Event_Gadget
quit=#MAXSHORT
Case #WM_TIMER
quit+1
;SetGadgetText(2,Str(quit))
Case #WM_CHAR
Select EventwParam()
Case 13,32,27
quit=#MAXSHORT
EndSelect
;Default
;SetGadgetText(2,Str(event))
EndSelect
Until quit>wait
CloseWindow(1)
EndIf
EndProcedure
Procedure ClearCounter()
Protected i
For i=1 To 4
Counter(i)=0
Next i
Total=0
EndProcedure
Procedure ClearSessions()
Protected i
For i=0 To #MaxSessions
Sessions(i)=0
Next i
EndProcedure
Procedure.l NewSession(IP)
Protected i=0
If #MehrfachAntworten
ProcedureReturn #True; für Testzwecke - alles ist erlaubt!
EndIf
Repeat
If Sessions(i)=0
Sessions(i)=IP
ProcedureReturn #True; unbekannte Session (neu)
ElseIf Sessions(i)=IP
ProcedureReturn #False; bekannte Session
EndIf
i+1
Until i=#MaxSessions
ProcedureReturn #False; zuviele Sessions aktiv
EndProcedure
Procedure.l Prozent(i)
ProcedureReturn #RandY+#BarY*(100-i)/100
EndProcedure
Procedure Haudrauf()
Protected i,j,n
n=100
For i=1 To 4
If (Bingo(i)<n) And (Bingo(i)>0)
n=Bingo(i)
j=i
EndIf
Next i
Bingo(j)+1
EndProcedure
Procedure DrawBars()
StartDrawing(ImageOutput(0))
Box(0,0,#BildX,#BildY,$800000)
For i=0 To 10
y=Prozent(i*10)
LineXY(#RandX>>1,y,#BildX-#RandX+1,y,#Blue)
Next i
If Total
j=0
For i=1 To 4
Bingo(i)=Counter(i)*100/Total
j+Bingo(i)
Next i
If j<100
Haudrauf()
j+1
EndIf
For i=1 To 4
y=Prozent(Bingo(i))
Box(#RandX+(i-1)*(#BarX+#BarZ),y,#BarX-1,#RandY+#BarY-y+1,#Red)
Next i
DrawingFont(FontID(0))
DrawingMode(#PB_2DDrawing_Transparent)
For i=1 To 4
dummy=Str(Bingo(i))+"%"
x=TextWidth(dummy)>>1+1
DrawText(#RandX+(i-1)*(#BarX+#BarZ)+#BarX>>1-x,#RandY,dummy,#White)
Next i
DrawingFont(FontID(1))
For i=1 To 4
dummy=Chr(64+i);Str(i);"25%"
x=TextWidth(dummy)>>1+1
DrawText(#RandX+(i-1)*(#BarX+#BarZ)+#BarX>>1-x,#BarY+#RandY+2,dummy,#White)
Next i
Else
DrawingFont(FontID(0))
DrawingMode(#PB_2DDrawing_Transparent)
If Modus=#AkzeptiereNachrichten
dummy="Bitte Wertung abgeben!"
Else
dummy="Keine Wertung!"
EndIf
x=TextWidth(dummy)>>1+1
y=TextHeight(dummy)>>1+1
DrawText(#BildX>>1-x,#BildY>>1-y,dummy,#White)
EndIf
StopDrawing()
SetGadgetState(#Bild,ImageID)
EndProcedure
Procedure InitServer()
If InitNetwork()=0
Meldung("Fehler","Kein Netzwerk verfügbar!",#IDI_HAND)
End
EndIf
If CreateNetworkServer(#ServerID, #ServerPort,#PB_Network_TCP)=0
Meldung("Fehler","Der Server kann nicht gestartet werden!",#IDI_HAND)
End
EndIf
EndProcedure
Procedure Main()
Init()
InitServer()
WinID=OpenWindow(0,0,0,#WinX,#WinY,"ABCD-Server",#PB_Window_ScreenCentered|#PB_Window_Invisible|#PB_Window_SystemMenu)
;LoadFont(0,"Trebuchet MS",64)
CreateGadgetList(WinID)
ButtonGadget(#Start,#RandX,#BildY+#WinRand+12,#BildX,28,#Starttext)
ButtonGadget(#Ende,#RandX,#BildY+#WinRand+46,#BildX,28,"Ende")
ImageGadget(#Bild,#WinRand-1,#WinRand,#BildX,#BildY,ImageID,#PB_Image_Border)
AddKeyboardShortcut(0,#PB_Shortcut_Escape,666)
AddKeyboardShortcut(0,#PB_Shortcut_S,#Start)
SetTimer_(WinID,1,100,0)
DrawBars()
HideWindow(0,0)
Repeat
Select WaitWindowEvent()
Case #PB_Event_Gadget,#PB_Event_Menu
Select EventGadget()
Case #Start
ClearSessions()
ClearCounter()
Modus=#AkzeptiereNachrichten
DrawBars()
Sekunden=#Pollzeit
DisableGadget(#Start,1)
DisableGadget(#Ende,1)
Case #Ende
quit=#True
Case 666
If Modus=#IgnoriereNachrichten : quit=1 : EndIf
EndSelect
Case #WM_TIMER
If Modus=#AkzeptiereNachrichten
If Sekunden
Sekunden-1
SetGadgetText(#Start,StrF(Sekunden/10,1)+" Sek.")
Else
SetGadgetText(#Start,#Starttext)
Modus=#IgnoriereNachrichten
DrawBars()
DisableGadget(#Start,0)
DisableGadget(#Ende,0)
EndIf
EndIf
Case #PB_Event_CloseWindow
If Modus=#IgnoriereNachrichten : quit=1 : EndIf
EndSelect
Event=NetworkServerEvent()
ClientID=EventClient()
If ClientID
ClientIP=GetClientIP(ClientID)
EndIf
Select Event
;Case #PB_NetworkEvent_Connect
;Debug "Client connected, ip/hostname: "+IPString(ClientIP)
;Case #PB_NetworkEvent_Disconnect
;Debug "Client disconnected "+IPString(ClientIP)
Case #PB_NetworkEvent_Data
ok=NewSession(ClientIP)
ok=(ReceiveNetworkData(ClientID,@ABCD,4)) And ok
If ok And (Modus=#AkzeptiereNachrichten)
If (ABCD>'@') And (ABCD<'E')
Counter(ABCD-64)+1
Total+1
EndIf
;Debug Chr(ABCD)
;Else
;Debug Chr(ABCD)+" ignored"
EndIf
EndSelect
Until Quit=1
CloseNetworkServer(#ServerID)
EndProcedure
Main()
Client
Code: Select all
Procedure Init()
EnableExplicit
#MaxServer=10
#ServerID=666
#ServerPort=6699
#Ausszeit=10000
Global ABCD
Global SessionID
Global Dim Server.s(#MaxServer)
Global i,x,y
Global Server
Global Dummy.s
Global Blockierung
Global WinID
Global quit
Global Font
EndProcedure
Procedure.w Limit(low.w,med.w,high.w)
If med<low
ProcedureReturn low
ElseIf med>high
ProcedureReturn high
Else
ProcedureReturn med
EndIf
EndProcedure
Procedure Meldung(titel.s,meldung.s,icon=#IDI_ASTERISK,wait=30)
;#IDI_QUESTION ; (?)
;#IDI_HAND ; (X)
;#IDI_EXCLAMATION ; /!\
;#IDI_ASTERISK ; (i)
Define mouse.point
#Hoehe=64 ; mit Ok-Knopf: 96
GetCursorPos_(@mouse)
x=limit(0,(mouse\x)-130,GetSystemMetrics_(#SM_CXSCREEN)-260)
y=limit(0,(mouse\y)-100,GetSystemMetrics_(#SM_CYSCREEN)-#hoehe)
If OpenWindow(1,x,y,272,#hoehe,titel,#PB_Window_SystemMenu|#PB_Window_Invisible)
CreateGadgetList(WindowID(1))
ImageGadget(1, 12, 14, 0, 0, LoadIcon_(0,icon))
TextGadget(2,60,20,250,30,meldung)
DisableGadget(1,1)
HideWindow(1, 0)
quit=0
SetTimer_(WindowID(1),1,80,0) ; Default: 100ms
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow,#PB_Event_Gadget
quit=#MAXSHORT
Case #WM_TIMER
quit+1
;SetGadgetText(2,Str(quit))
Case #WM_CHAR
Select EventwParam()
Case 13,32,27
quit=#MAXSHORT
EndSelect
;Default
;SetGadgetText(2,Str(event))
EndSelect
Until quit>wait
CloseWindow(1)
EndIf
EndProcedure
Procedure.l CheckServer(IP.s,Port) ;nur echte IP-Adressen verwenden
Define *host.HOSTENT
Define was.WSADATA
Define IPAddress
Define s
Define ret=#False
Define addr.SOCKADDR_IN
Define version=(2<<8)+1
If WSAStartup_(version,@was.WSADATA)=0
*host=gethostbyname_(IP)
If *host<>#Null
IpAddress=PeekL(*host\h_addr_list)
IP=StrU(PeekB(IpAddress),0)+"."+StrU(PeekB(IpAddress+1),0)+"."+StrU(PeekB(IpAddress+2),0)+"."+StrU(PeekB(IpAddress+3),0)
s=SOCKET_(#AF_INET,#SOCK_STREAM,0);
If s<>#INVALID_SOCKET
addr.SOCKADDR_IN
addr\sin_family= #AF_INET;
addr\sin_port= htons_(Port)
addr\sin_addr= inet_addr_(IP)
If connect_(s,@addr.SOCKADDR_IN,SizeOf(SOCKADDR_IN)) <> #SOCKET_ERROR
ret=#True
EndIf
closesocket_(s)
EndIf
EndIf
WSACleanup_()
EndIf
ProcedureReturn ret
EndProcedure
Procedure InitClient()
If InitNetwork()=0
Meldung("Fehler","Kein Netzwerk verfügbar!",#IDI_HAND)
End
EndIf
; Einlesen von bis zu #MaxServer Namen von Servern (Index 0 bis höchstens #MaxServer-1)
i=0
#Datei="ABCD.ini"
If FileSize(#Datei)>0
ReadFile(0,#Datei)
While (i<#MaxServer) And (Eof(0)=0)
Dummy=Trim(ReadString(0))
If Len(Dummy)
Server(i)=Dummy
i+1
EndIf
Wend
CloseFile(0)
EndIf
; Einlesen von vordefinierten Servern (Index n bis höchstens #MaxServer)
Repeat
Read Dummy
If Dummy="*" : Break : EndIf
Server(i)=Dummy
i+1
Until i>#MaxServer
Server=i
DataSection
Data.s "vo-notebook"
Data.s "*"
EndDataSection
i=0
Repeat
If CheckServer(Server(i),#ServerPort)
SessionID=OpenNetworkConnection(Server(i),#ServerPort)
If SessionID : Break : EndIf
EndIf
i+1
Until i=Server
If SessionID=0
Meldung("Fehler","Server-Anwendung nicht gefunden!",#IDI_HAND)
End
EndIf
EndProcedure
Procedure DisableButtons(auswahl)
For x=1 To 4
If x=auswahl
SetGadgetText(x,Chr(x+64))
Else
SetGadgetText(x,"·")
EndIf
DisableGadget(x,1)
Next x
Blockierung=GetTickCount_()+#Ausszeit
EndProcedure
Procedure EnableButtons()
If Blockierung
If GetTickCount_()>Blockierung
Blockierung=0
For x=1 To 4
SetGadgetText(x,Chr(x+64))
DisableGadget(x,0)
Next x
EndIf
EndIf
EndProcedure
Procedure Main()
Init()
InitClient()
#ButtonX=96
#ButtonY=96
WinID=OpenWindow(0,0,0,#ButtonX<<2,#ButtonY,"ABCD-Client",#PB_Window_ScreenCentered|#PB_Window_Invisible|#PB_Window_SystemMenu)
LoadFont(0,"Trebuchet MS",64)
SetGadgetFont(#PB_Default,FontID(0))
CreateGadgetList(WinID)
For i=0 To 3
ButtonGadget(i+1,i*#ButtonX,0,#ButtonX,#ButtonY,Chr(65+i))
Next i
AddKeyboardShortcut(0,#PB_Shortcut_A,1)
AddKeyboardShortcut(0,#PB_Shortcut_B,2)
AddKeyboardShortcut(0,#PB_Shortcut_C,3)
AddKeyboardShortcut(0,#PB_Shortcut_D,4)
AddKeyboardShortcut(0,#PB_Shortcut_Escape,666)
SetTimer_(WinID,1,100,0)
HideWindow(0,0)
quit=0
Repeat
Select WaitWindowEvent()
Case #PB_Event_Gadget,#PB_Event_Menu
i=EventGadget()
Select i
Case 1 To 4
DisableButtons(i)
ABCD=i+64
SendNetworkData(SessionID,@ABCD,4)
Delay(100)
Case 666
quit=1
EndSelect
Case #PB_Event_CloseWindow
quit=1
Case #WM_TIMER
EnableButtons()
EndSelect
Until quit
CloseNetworkConnection(SessionID)
EndProcedure
Main()