[Done] CloseNetworkConnection()
[Done] CloseNetworkConnection()
Hi
I notice that after using the CloseNetworkConnection() function I am unable to reopen the port unless I wait 1-2 minutes, otherwise OpenNetworkConnection() fails even if the connection is for a local port on the same PC. So I am wondering why this should be the case. Does CloseNetworkConnection() close the port gracefully so that the server knows the connection has been closed?
I am running OpenSuse 15.3 using PB 5.73.
Thanks,
Simon
I notice that after using the CloseNetworkConnection() function I am unable to reopen the port unless I wait 1-2 minutes, otherwise OpenNetworkConnection() fails even if the connection is for a local port on the same PC. So I am wondering why this should be the case. Does CloseNetworkConnection() close the port gracefully so that the server knows the connection has been closed?
I am running OpenSuse 15.3 using PB 5.73.
Thanks,
Simon
Simon White
dCipher Computing
dCipher Computing
Re: CloseNetworkConnection()
It's the same on debian stretch/buster/bullseye.
When I have to restart a PB daemon, I have to add a loop for creating the server, because it takes time until the OS allows it again.
You can check if the port is still in CLOSE_WAIT state via netstat.
When I have to restart a PB daemon, I have to add a loop for creating the server, because it takes time until the OS allows it again.
You can check if the port is still in CLOSE_WAIT state via netstat.
Re: CloseNetworkConnection()
It is likely due to socket security, check out ss (ss --tcp state CLOSE-WAIT --kill)
Re: CloseNetworkConnection()
I just checked it:
The used port is not listed after terminating the program (ss -tulpn).
But it is not possible to start the program again.
It needs arround 30 seconds until it's possible to create the server again.
The used port is not listed after terminating the program (ss -tulpn).
But it is not possible to start the program again.
It needs arround 30 seconds until it's possible to create the server again.
Re: CloseNetworkConnection()
Short code to test it:
connect via
telnet 127.0.0.1 4444
after leaving via exit, it is not possible to restart the code above until some time is gone.
Code: Select all
InitNetwork()
If CreateNetworkServer(0, 4444)
*Buffer = AllocateMemory(1024)
If *Buffer
Repeat
Select NetworkServerEvent()
Case #PB_NetworkEvent_Connect
Client = EventClient()
SendNetworkString(Client, #CRLF$ + "Welcome! Type 'exit' to leave." + #CRLF$ + #CRLF$)
Case #PB_NetworkEvent_Data
Client = EventClient()
Len = ReceiveNetworkData(Client, *Buffer, MemorySize(*Buffer))
If Len
Rcv$ = PeekS(*Buffer, Len, #PB_UTF8|#PB_ByteLength)
Debug Rcv$
SendNetworkString(Client, "Answer: " + Rcv$)
If FindString(Rcv$, "exit")
Exit = #True
EndIf
EndIf
Case #PB_NetworkEvent_None
Delay(5)
EndSelect
Until Exit
FreeMemory(*Buffer)
EndIf
CloseNetworkServer(0)
EndIf
telnet 127.0.0.1 4444
after leaving via exit, it is not possible to restart the code above until some time is gone.
Re: CloseNetworkConnection()
WIth
ss -a|grep 4444
I can see
ss -a|grep 4444
I can see
tcp TIME-WAIT 0 0 127.0.0.1:4444 127.0.0.1:54974
Re: CloseNetworkConnection()
I just checked that a small node server doesn't have this problem.
When I do exacly the same I can not see a TIME-WAIT socket after closing the server.
Maybe he waits in the close code to receive the FIN packets from all open connections.
And it tooks 60 seconds until I can restart the server.
That's not really acceptable for a service which needs to restart cause of an update or something similar.
When I do exacly the same I can not see a TIME-WAIT socket after closing the server.
Maybe he waits in the close code to receive the FIN packets from all open connections.
And it tooks 60 seconds until I can restart the server.
That's not really acceptable for a service which needs to restart cause of an update or something similar.
Re: CloseNetworkConnection()
Fred need to add
before he bind in the CreateNetworkServer() procedure.
Code: Select all
Flag.l = 1
setsockopt_(ServerID, #SOL_SOCKET, #SO_REUSEADDR, @Flag, SizeOf(Flag))
Re: CloseNetworkConnection()
Found a (bug)fix:
Not a nice solution, but it works.
SO_REUSEADDR is the way to go, but not possible from a PB coder. It's an internal solution.
Code: Select all
EnableExplicit
#SOL_SOCKET = 1
#SO_REUSEADDR = 2
#SO_LINGER = 13
#SO_REUSEPORT = 15
ImportC ""
errno_location() As "__errno_location"
EndImport
Structure SO_LINGER_Structure
l_onoff.l
l_linger.l
EndStructure
Define Server.i, res.i, errno.l, *Buffer, Client.i, Len.i, Rcv$, Exit.i
Define SoLinger.SO_LINGER_Structure
InitNetwork()
Server = CreateNetworkServer(#PB_Any, 4444)
If Server
SoLinger\l_onoff = #True
SoLinger\l_linger = 0
res = setsockopt_(ServerID(Server), #SOL_SOCKET, #SO_LINGER, @SoLinger, SizeOf(SO_LINGER_Structure))
If res <> 0
errno = PeekL(errno_location())
Debug PeekS(strerror_(errno), -1, #PB_Ascii)
EndIf
*Buffer = AllocateMemory(1024)
If *Buffer
Repeat
Select NetworkServerEvent()
Case #PB_NetworkEvent_Connect
Client = EventClient()
SendNetworkString(Client, #CRLF$ + "Welcome! Type 'exit' to leave." + #CRLF$ + #CRLF$)
Case #PB_NetworkEvent_Data
Client = EventClient()
Len = ReceiveNetworkData(Client, *Buffer, MemorySize(*Buffer))
If Len
Rcv$ = PeekS(*Buffer, Len, #PB_UTF8|#PB_ByteLength)
SendNetworkString(Client, "Answer: " + Rcv$)
If FindString(Rcv$, "exit")
Exit = #True
EndIf
EndIf
Case #PB_NetworkEvent_None
Delay(5)
EndSelect
Until Exit
FreeMemory(*Buffer)
EndIf
CloseNetworkServer(Server)
EndIf
SO_REUSEADDR is the way to go, but not possible from a PB coder. It's an internal solution.
- NicTheQuick
- Addict
- Posts: 1224
- Joined: Sun Jun 22, 2003 7:43 pm
- Location: Germany, Saarbrücken
- Contact:
Re: CloseNetworkConnection()
+1
Should be changed and fixed.
Should be changed and fixed.
The english grammar is freeware, you can use it freely - But it's not Open Source, i.e. you can not change it or publish it in altered way.
Re: CloseNetworkConnection()
To be investigated
-
- User
- Posts: 42
- Joined: Sat Oct 18, 2014 7:14 am
Re: CloseNetworkConnection()
Unfortunately, the example from infantec doesn't work for me.
That's why I always program under Linux with the Windows version under Wine. Unfortunately, the icons are no longer displayed with Wine because Fred removed them with version 5.50.
It would be nice if they were there again in case the problem cannot be solved.
That's why I always program under Linux with the Windows version under Wine. Unfortunately, the icons are no longer displayed with Wine because Fred removed them with version 5.50.
It would be nice if they were there again in case the problem cannot be solved.
- NicTheQuick
- Addict
- Posts: 1224
- Joined: Sun Jun 22, 2003 7:43 pm
- Location: Germany, Saarbrücken
- Contact:
Re: CloseNetworkConnection()
There's also an old post from me in the German forum: https://www.purebasic.fr/german/viewtop ... 23#p356023
Don't change the Longs into Integer. It's essential if I remember correctly.
I did not recheck if it still works.So if I see this correctly, you can extract the socket number from the handle of CreateNetworkServer() and use it directly. The prerequisite is that you use #PB_Any.
I have prepared something for you. Basically, you only have to put the big CompilerIf above into your existing code and you can leave the rest as it was before.Code: Select all
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")
Don't change the Longs into Integer. It's essential if I remember correctly.
The english grammar is freeware, you can use it freely - But it's not Open Source, i.e. you can not change it or publish it in altered way.
-
- User
- Posts: 42
- Joined: Sat Oct 18, 2014 7:14 am
Re: CloseNetworkConnection()
Unfortunately it doesn't work, but thank you for your efforts!
-
- User
- Posts: 42
- Joined: Sat Oct 18, 2014 7:14 am
Re: CloseNetworkConnection()
No change in BP 6.10 beta 4