Webserver bzw. Problem mit SendNetworkData()
- NicTheQuick
- Ein Admin
- Beiträge: 8679
- Registriert: 29.08.2004 20:20
- Computerausstattung: Ryzen 7 5800X, 32 GB DDR4-3200
Ubuntu 22.04.3 LTS
GeForce RTX 3080 Ti - Wohnort: Saarbrücken
- Kontaktdaten:
Re: Webserver bzw. Problem mit SendNetworkData()
Wie hast du das denn "so" in PB aufgerufen? Wo kommen de Variablen her, die eigentlich Konstanten sein sollten? Und was sind htons() und inet_addr()? Dein Code ist so doch gar nicht lauffähig.
Re: Webserver bzw. Problem mit SendNetworkData()
Das ist im Prinzip das, was "strace netcat -l 0.0.0.0 80" ausgeworfen hat:
nur ein bisschen so modifiziert, dass PB es überhaupt schluckt.
Klar, dass das nicht funktionieren kann, aber ich habe leider keine Ahnung, wie ich die geforderten Parameter übergeben kann.
Code: Alles auswählen
socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) = 3
setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
setsockopt(3, SOL_SOCKET, SO_REUSEPORT, [1], 4) = 0
bind(3, {sa_family=AF_INET, sin_port=htons(80), sin_addr=inet_addr("0.0.0.0")}, 16) = 0
listen(3, 1)
Klar, dass das nicht funktionieren kann, aber ich habe leider keine Ahnung, wie ich die geforderten Parameter übergeben kann.
Gruß
Markus
Markus
- NicTheQuick
- Ein Admin
- Beiträge: 8679
- Registriert: 29.08.2004 20:20
- Computerausstattung: Ryzen 7 5800X, 32 GB DDR4-3200
Ubuntu 22.04.3 LTS
GeForce RTX 3080 Ti - Wohnort: Saarbrücken
- Kontaktdaten:
Re: Webserver bzw. Problem mit SendNetworkData()
Das musst du natürlich alles erst mal übersetzen, sprich die Konstanten und Strukturen zusammensuchen und in Purebasic verügbar machen und dann entsprechend anwenden.
Hier mal ein auf die Schnelle zusammengeschustertes Beispiel, was noch nicht komplett funktioniert.
Es öffnet einen Socket auf Port 8080, zu dem man sich verbinden kann. Sobald die Verbindung steht, sollte eigentlich ein Text gesendet werden, was aber nicht funktioniert. Vielleicht muss man noch TCP_NODELAY setzen, wie hier erwähnt wird: https://stackoverflow.com/a/7400391/4239139
Hier mal ein auf die Schnelle zusammengeschustertes Beispiel, was noch nicht komplett funktioniert.
Es öffnet einen Socket auf Port 8080, zu dem man sich verbinden kann. Sobald die Verbindung steht, sollte eigentlich ein Text gesendet werden, was aber nicht funktioniert. Vielleicht muss man noch TCP_NODELAY setzen, wie hier erwähnt wird: https://stackoverflow.com/a/7400391/4239139
Code: Alles auswählen
EnableExplicit
#AF_INET = 2
#SOCK_STREAM = 1
#IPPROTO_TCP = 6
#SOL_SOCKET = 1
#SO_REUSEADDR = 2
#SO_REUSEPORT = 15
Structure in_addr
s_addr.l
EndStructure
Structure sockaddr_in
sin_family.w
sin_port.u
sin_addr.in_addr
sin_zero.a[8]
EndStructure
Define.i hSocket = socket_(#AF_INET, #SOCK_STREAM, #IPPROTO_TCP)
If hSocket < 0
Debug "Error opening socket."
End
EndIf
Debug "Socket = " + hSocket
Define enable.l = 1
If setsockopt_(hSocket, #SOL_SOCKET, #SO_REUSEADDR, @enable, SizeOf(enable)) < 0
Debug "Error setting SO_REUSEADDR"
End
EndIf
If setsockopt_(hSocket, #SOL_SOCKET, #SO_REUSEPORT, @enable, SizeOf(enable)) < 0
Debug "Error setting SO_REUSEPORT"
End
EndIf
Define serverInfo.sockaddr_in
serverInfo\sin_family = #AF_INET
serverInfo\sin_port = htons_(8080)
inet_aton_("0.0.0.0", @serverInfo\sin_addr)
If bind_(hSocket, @serverInfo, SizeOf(serverInfo)) < 0
Debug "Error binding socket."
End
EndIf
If listen_(hSocket, 1) < 0
Debug "Error listening on socket."
End
EndIf
Define clientSocket.sockaddr_in
Define newConnection.i = accept_(hSocket, @clientSocket, SizeOf(clientSocket))
If newConnection < 0
Debug "Error accepting incoming connection."
End
EndIf
Define *utf8Text = UTF8("Hello World")
send_(newConnection, *utf8Text, MemorySize(*utf8Text), 0)
FreeMemory(*utf8Text)
Delay(1000)
close_(newConnection)
close_(hSocket)
Re: Webserver bzw. Problem mit SendNetworkData()
Vielen Dank für Deine Mühe NicTheQuick,
aber ich fürchte, das krieg ich nicht hin.
Man müsste dann ja auch irgendwie mit den PB-Netzwerkbefehlen darauf zugreifen können (NetworkServerEvent(), EventClient(), ReceiveNetworkData(), SendNetworkData() etc.).
Wäre es nicht sinnvoller Fred einmal auf diesen gravierenden Bug hinzuweisen, der ja eigentlich schon seit über zehn Jahren bekannt ist, wie ich hier gesehen habe: viewtopic.php?f=3&t=19047&hilit=setsockopt
aber ich fürchte, das krieg ich nicht hin.
Man müsste dann ja auch irgendwie mit den PB-Netzwerkbefehlen darauf zugreifen können (NetworkServerEvent(), EventClient(), ReceiveNetworkData(), SendNetworkData() etc.).
Wäre es nicht sinnvoller Fred einmal auf diesen gravierenden Bug hinzuweisen, der ja eigentlich schon seit über zehn Jahren bekannt ist, wie ich hier gesehen habe: viewtopic.php?f=3&t=19047&hilit=setsockopt
Gruß
Markus
Markus
- NicTheQuick
- Ein Admin
- Beiträge: 8679
- Registriert: 29.08.2004 20:20
- Computerausstattung: Ryzen 7 5800X, 32 GB DDR4-3200
Ubuntu 22.04.3 LTS
GeForce RTX 3080 Ti - Wohnort: Saarbrücken
- Kontaktdaten:
Re: Webserver bzw. Problem mit SendNetworkData()
Also wenn ich das richtig sehe, dann kann man aus dem Handle von CreateNetworkServer() die Socket-Nummer extrahieren und direkt nutzen. Voraussetzung ist, dass man #PB_Any nutzt.
Ich habe dir mal etwas vorbereitet. Im Grunde musst du nur das große CompilerIf oben in deinen schon vorhandenen Code stecken und den Rest kannst du so lassen wie er bisher war.
Ich habe dir mal etwas vorbereitet. Im Grunde musst du nur das große CompilerIf oben in deinen schon vorhandenen Code stecken und den Rest kannst du so lassen wie er bisher war.
Code: Alles auswählen
EnableExplicit
CompilerIf #PB_Compiler_OS = #PB_OS_Linux
#SOL_SOCKET = 1
#SO_REUSEADDR = 2
#SO_REUSEPORT = 15
Procedure CreateNetworkServerEx(ServerID.i, Port.i, Modus, BindedIP$)
Protected handle.i
If ServerID.i = #PB_Any
handle.i = CreateNetworkServer(#PB_Any, Port, Modus, BindedIP$)
If Not handle
ProcedureReturn handle
EndIf
Protected hSocket.l = PeekL(handle), enable.l = 1
If setsockopt_(hSocket, #SOL_SOCKET, #SO_REUSEADDR, @enable, SizeOf(enable)) < 0
Debug "Error setting SO_REUSEADDR"
End
EndIf
If setsockopt_(hSocket, #SOL_SOCKET, #SO_REUSEPORT, @enable, SizeOf(enable)) < 0
Debug "Error setting SO_REUSEPORT"
End
EndIf
ProcedureReturn handle
Else
ProcedureReturn CreateNetworkServer(ServerID, Port, Modus, BindedIP$)
EndIf
EndProcedure
Macro CreateNetworkServer(a, b, c = #PB_Network_TCP | #PB_Network_IPv4, d = "0.0.0.0")
CreateNetworkServerEx(a, b, c, d)
EndMacro
CompilerEndIf
InitNetwork()
Define a.i = CreateNetworkServer(#PB_Any, 8080, #PB_Network_TCP, "0.0.0.0")
Re: Webserver bzw. Problem mit SendNetworkData()
Wahnsinn, das funktioniert!
Der Port ist sofort wieder frei.
Tausend Dank NicTheQuick
Du bist ja so was von genial!!!
Kann's noch garnicht fassen.
Der Port ist sofort wieder frei.
Tausend Dank NicTheQuick
Du bist ja so was von genial!!!
Kann's noch garnicht fassen.
Gruß
Markus
Markus
- NicTheQuick
- Ein Admin
- Beiträge: 8679
- Registriert: 29.08.2004 20:20
- Computerausstattung: Ryzen 7 5800X, 32 GB DDR4-3200
Ubuntu 22.04.3 LTS
GeForce RTX 3080 Ti - Wohnort: Saarbrücken
- Kontaktdaten:
Re: Webserver bzw. Problem mit SendNetworkData()
Freut mich.Gimbly hat geschrieben:Wahnsinn, das funktioniert!
Der Port ist sofort wieder frei.
Übertreib nicht so viel.Tausend Dank NicTheQuick
Du bist ja so was von genial!!!
Re: Webserver bzw. Problem mit SendNetworkData()
Leider zu früh gefreut.
Hatte nicht richtig getestet.
Sobald es einen Request gab, bleibt der Port nach Beenden wie gehabt 60 Sekunden lang gesperrt.
Hatte nicht richtig getestet.
Sobald es einen Request gab, bleibt der Port nach Beenden wie gehabt 60 Sekunden lang gesperrt.
Gruß
Markus
Markus
- NicTheQuick
- Ein Admin
- Beiträge: 8679
- Registriert: 29.08.2004 20:20
- Computerausstattung: Ryzen 7 5800X, 32 GB DDR4-3200
Ubuntu 22.04.3 LTS
GeForce RTX 3080 Ti - Wohnort: Saarbrücken
- Kontaktdaten:
Re: Webserver bzw. Problem mit SendNetworkData()
Erklär mal bitte genau die Reihenfolge und die Dinge, die du machst, dass es 60 Sekunden lang nicht mehr geht.
Re: Webserver bzw. Problem mit SendNetworkData()
Also Du startest den Atomic-Webserver und machst dann über den Browser einen Request: localhost:8080.
Es kommt ordnungsgemäß die Index.html.
Wenn Du dann irgendwann den Webserver beendest, ist ab dann etwa 60 Sek. lang der Port 8080 gesperrt. Erst dann kannst Du den Webserver wieder starten.
Wenn Du den Webserver allerdings beendest, ohne dass während seiner Laufzeit ein Request stattgefunden hat, ist der Port 8080 sofort frei und Du kannst ihn sofort neu starten.
Es kommt ordnungsgemäß die Index.html.
Wenn Du dann irgendwann den Webserver beendest, ist ab dann etwa 60 Sek. lang der Port 8080 gesperrt. Erst dann kannst Du den Webserver wieder starten.
Wenn Du den Webserver allerdings beendest, ohne dass während seiner Laufzeit ein Request stattgefunden hat, ist der Port 8080 sofort frei und Du kannst ihn sofort neu starten.
Zuletzt geändert von Gimbly am 14.02.2020 14:08, insgesamt 1-mal geändert.
Gruß
Markus
Markus