Webserver bzw. Problem mit SendNetworkData()

In dieser Linux-Ecke dürfen nur Themen rund um Linux geschrieben werden.
Beiträge, die plattformübergreifend sind, gehören ins 'Allgemein'-Forum.
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8375
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 32 GB DDR4-3200
Ubuntu 20.10
NVIDIA Quadro P2200
Wohnort: Saarbrücken
Kontaktdaten:

Re: Webserver bzw. Problem mit SendNetworkData()

Beitrag von NicTheQuick »

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.
Bild
Gimbly
Beiträge: 169
Registriert: 28.12.2005 14:26
Wohnort: NRW

Re: Webserver bzw. Problem mit SendNetworkData()

Beitrag von Gimbly »

Das ist im Prinzip das, was "strace netcat -l 0.0.0.0 80" ausgeworfen hat:

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)
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.
Gruß
Markus
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8375
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 32 GB DDR4-3200
Ubuntu 20.10
NVIDIA Quadro P2200
Wohnort: Saarbrücken
Kontaktdaten:

Re: Webserver bzw. Problem mit SendNetworkData()

Beitrag von NicTheQuick »

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

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)
Bild
Gimbly
Beiträge: 169
Registriert: 28.12.2005 14:26
Wohnort: NRW

Re: Webserver bzw. Problem mit SendNetworkData()

Beitrag von Gimbly »

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
Gruß
Markus
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8375
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 32 GB DDR4-3200
Ubuntu 20.10
NVIDIA Quadro P2200
Wohnort: Saarbrücken
Kontaktdaten:

Re: Webserver bzw. Problem mit SendNetworkData()

Beitrag von NicTheQuick »

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.

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")
Bild
Gimbly
Beiträge: 169
Registriert: 28.12.2005 14:26
Wohnort: NRW

Re: Webserver bzw. Problem mit SendNetworkData()

Beitrag von Gimbly »

Wahnsinn, das funktioniert!

Der Port ist sofort wieder frei.

Tausend Dank NicTheQuick

Du bist ja so was von genial!!!

Kann's noch garnicht fassen.
Gruß
Markus
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8375
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 32 GB DDR4-3200
Ubuntu 20.10
NVIDIA Quadro P2200
Wohnort: Saarbrücken
Kontaktdaten:

Re: Webserver bzw. Problem mit SendNetworkData()

Beitrag von NicTheQuick »

Gimbly hat geschrieben:Wahnsinn, das funktioniert!

Der Port ist sofort wieder frei.
Freut mich. <)
Tausend Dank NicTheQuick

Du bist ja so was von genial!!!
Übertreib nicht so viel. :wink:
Bild
Gimbly
Beiträge: 169
Registriert: 28.12.2005 14:26
Wohnort: NRW

Re: Webserver bzw. Problem mit SendNetworkData()

Beitrag von Gimbly »

Leider zu früh gefreut. :cry:

Hatte nicht richtig getestet.

Sobald es einen Request gab, bleibt der Port nach Beenden wie gehabt 60 Sekunden lang gesperrt.
Gruß
Markus
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8375
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 32 GB DDR4-3200
Ubuntu 20.10
NVIDIA Quadro P2200
Wohnort: Saarbrücken
Kontaktdaten:

Re: Webserver bzw. Problem mit SendNetworkData()

Beitrag von NicTheQuick »

Erklär mal bitte genau die Reihenfolge und die Dinge, die du machst, dass es 60 Sekunden lang nicht mehr geht.
Bild
Gimbly
Beiträge: 169
Registriert: 28.12.2005 14:26
Wohnort: NRW

Re: Webserver bzw. Problem mit SendNetworkData()

Beitrag von Gimbly »

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.
Zuletzt geändert von Gimbly am 14.02.2020 14:08, insgesamt 1-mal geändert.
Gruß
Markus
Antworten