hello everyone !
i have a question : Can i create multiple socket servers within only 1 standalone software, and each socket instance within this single software be named without having to change the port?
like this example (Address to connect):
127.0.0.1:5566/MyServerSocket001
127.0.0.1:5566/MyServerSocket002
127.0.0.1:5566/MyServerSocket003
127.0.0.1:5566/MyServerSocket004
note that everyone is using the same IP and PORT
each running independently ?
like : Jetty Handlers ( JAVA ) https://www.eclipse.org/jetty/documenta ... mples.html
how can i "handle" socket server ?
- skinkairewalker
- Enthusiast
- Posts: 637
- Joined: Fri Dec 04, 2015 9:26 pm
Re: how can i "handle" socket server ?
There can only be one socket per port.
In this socket you have to evaluate from which client the request comes.
In this socket you have to evaluate from which client the request comes.
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
- skinkairewalker
- Enthusiast
- Posts: 637
- Joined: Fri Dec 04, 2015 9:26 pm
Re: how can i "handle" socket server ?
can i disconnect client and force this same client to connect to server what i want ?
Re: how can i "handle" socket server ?
The server can receive several simultaneous connections and reply to differents clients (socket mechanism), it recognizes each of them by their IP ( GetClientIP() )
and port ( GetClientPort() ) source and assigns them an ID ( ConnectionID() )
You can of course disconnect this connection ( CloseNetworkConnection() ) but that's it.
Network Lib
and port ( GetClientPort() ) source and assigns them an ID ( ConnectionID() )
You can of course disconnect this connection ( CloseNetworkConnection() ) but that's it.
Network Lib
Re: how can i "handle" socket server ?
A server can also disconnect the client connection.
On the client you can also see that the connection has been disconnected from the server.
Small Server example (Not testet)
On the client you can also see that the connection has been disconnected from the server.
Small Server example (Not testet)
Code: Select all
;-TOP
; -----------------------------------------------------------------------------
CompilerIf #PB_Compiler_Thread = 0
CompilerError "Use Compiler-Option ThreadSafe"
CompilerEndIf
; -----------------------------------------------------------------------------
Enumeration FormWindow
#Main
EndEnumeration
Enumeration FormGadget
#MainList
EndEnumeration
Enumeration FormStatusBar
#MainStatusBar
EndEnumeration
Enumeration CustomEvent #PB_Event_FirstCustomValue
#MyEvent_Trace
EndEnumeration
; -----------------------------------------------------------------------------
Global ExitApplication
; -----------------------------------------------------------------------------
;#TraceList = -1 ; Use Debugger output
#TraceList = #MainList
Procedure __Trace(Info.s, Modul.s, Proc.s, Line)
Protected *msg.String = AllocateStructure(String)
If Modul = ""
Modul = "MainScope"
EndIf
*msg\s = FormatDate("[%HH:%II:%SS] ", Date())
*msg\s + "Module " + Modul + " | Proc " + Proc + " | Line " + Line + " | " + Info
PostEvent(#MyEvent_Trace, 0, 0, 0, *msg)
EndProcedure
; ---
Procedure DoEventTrace()
Protected *msg.String, cnt
*msg = EventData()
If *msg
If #TraceList >= 0 And IsGadget(#TraceList)
cnt = CountGadgetItems(#TraceList)
AddGadgetItem(#TraceList, -1, *msg\s)
SetGadgetState(#TraceList, cnt)
SetGadgetState(#TraceList, -1)
If cnt >= 1000
RemoveGadgetItem(#TraceList, 0)
EndIf
Else
Debug *msg\s
EndIf
FreeStructure(*msg)
EndIf
EndProcedure
; ---
Macro Trace(Info, Modul = #PB_Compiler_Module, Proc = #PB_Compiler_Procedure, Line = #PB_Compiler_Line)
__Trace(Info, Modul, Proc, Line)
EndMacro
BindEvent(#MyEvent_Trace, @DoEventTrace())
; -----------------------------------------------------------------------------
Procedure DoEventSizeWindow()
ResizeGadget(#MainList, 0, 0, WindowWidth(#Main), WindowHeight(#Main) - StatusBarHeight(#MainStatusBar))
EndProcedure
; -----------------------------------------------------------------------------
InitNetwork()
Declare thServer(*data)
Structure udtClient
ConnectionID.i
ConnectionTime.i
RequestTime.i
RequestString.s
EndStructure
Structure udtServerThread
; Header
ThreadID.i
Exit.i
; Configuration
Port.i
; Data
ServerID.i
Map Client.udtClient()
EndStructure
Global MyServer.udtServerThread
MyServer\Port = 6637
; -----------------------------------------------------------------------------
;- Main
Procedure Main()
Protected Event, ExitTime
#MainWidth = 800
#MainHeight = 600
#MainStyle = #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_MaximizeGadget | #PB_Window_MinimizeGadget
If OpenWindow(#Main, #PB_Ignore, #PB_Ignore, #MainWidth, #MainHeight, "Main Window", #MainStyle)
;-- Create StatusBar
CreateStatusBar(#MainStatusBar, WindowID(#Main))
AddStatusBarField(100) : StatusBarText(#MainStatusBar, 0, "Run")
AddStatusBarField(#PB_Ignore)
;-- Create Gadget
ListViewGadget(#MainList, 0, 0, #MainWidth, #MainHeight - StatusBarHeight(#MainStatusBar))
;-- BindEvent
BindEvent(#PB_Event_SizeWindow, @DoEventSizeWindow(), #Main)
Trace("Program started")
;-- Start Server
MyServer\ThreadID = CreateThread(@thServer(), MyServer)
;-- EventLoop
Repeat
Event = WaitWindowEvent()
Select Event
Case #PB_Event_CloseWindow
ExitApplication = #True
Case #PB_Event_Menu
Select EventMenu()
CompilerIf #PB_Compiler_OS = #PB_OS_MacOS
Case #PB_Menu_About
Case #PB_Menu_Preferences
Case #PB_Menu_Quit
ExitApplication = #True
CompilerEndIf
EndSelect
EndSelect
Until ExitApplication
MyServer\Exit = 1
;-- ExitProgram
Trace("Exit Program (Wait 2 Seconds)")
ExitTime = ElapsedMilliseconds()
Repeat
WaitWindowEvent(100)
If ElapsedMilliseconds() - ExitTime >= 2000
Break
EndIf
ForEver
EndIf
EndProcedure : Main()
End
; -----------------------------------------------------------------------------
Procedure thServer(*data.udtServerThread)
Protected ConnectionID, now
Protected *buffer, len
With *data
Delay(100)
\ServerID = CreateNetworkServer(#PB_Any, \Port)
If Not \ServerID
Trace("Server Error: Create Server with Port " + Str(\Port))
ProcedureReturn 0
Else
Trace("Server: Create Server with Port " + Str(\Port))
EndIf
*buffer = AllocateMemory($10000)
; Loop
Repeat
Select NetworkServerEvent()
Case #PB_NetworkEvent_Connect
ConnectionID = EventClient()
Trace("Server: Client connect with IP " + Str(GetClientIP(ConnectionID)))
If FindMapElement(\Client(), Hex(ConnectionID))
DeleteMapElement(\Client())
EndIf
AddMapElement(\Client(), Hex(ConnectionID))
\Client()\ConnectionTime = Date()
\Client()\RequestTime = Date()
Case #PB_NetworkEvent_Disconnect
ConnectionID = EventClient()
Trace("Server: Client disconnect with IP " + Str(GetClientIP(ConnectionID)))
If FindMapElement(\Client(), Hex(ConnectionID))
DeleteMapElement(\Client())
EndIf
Case #PB_NetworkEvent_Data
ConnectionID = EventClient()
Trace("Server: Client data with IP " + Str(GetClientIP(ConnectionID)))
If FindMapElement(\Client(), Hex(ConnectionID))
\Client()\RequestTime = Date()
len = ReceiveNetworkData(ConnectionID, *buffer, $10000)
\Client()\RequestString = PeekS(*buffer, len, #PB_Ascii)
; Send Echo
SendNetworkString(ConnectionID, \Client()\RequestString + #LF$, #PB_Ascii)
EndIf
Default
now = Date()
; Disconnect clients without request over 30 seconds
ForEach \Client()
If (now - \Client()\RequestTime) > 30
SendNetworkString(ConnectionID, "Timeout" + #LF$, #PB_Ascii)
CloseNetworkConnection(\Client()\ConnectionID)
DeleteMapElement(\Client())
EndIf
Next
Delay(100)
EndSelect
Until \Exit
Trace("Server: Shutdown")
ForEach \Client()
SendNetworkString(ConnectionID, "Server shutdown" + #LF$, #PB_Ascii)
CloseNetworkConnection(\Client()\ConnectionID)
Next
CloseNetworkServer(\ServerID)
; Exit Thread
EndWith
EndProcedure
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
Re: how can i "handle" socket server ?
If you write the client AND server software, yes you could do that in multiple ways. It isnt necessary though and if you want to achieve your initial goal (one server, one port which handles multiple connections), you can do that with the Purebasic network commands.skinkairewalker wrote:can i disconnect client and force this same client to connect to server what i want ?
A basic example is inside the manual - Network section called NetworkServer.pb
Just read all the command descriptions and it should be easy to follow. A common little test server to understand the concepts, would be a server which simply sends any incoming data back to the connected client. Then you can test it by simply connecting to your server and typing text. Let the server write back all of the client information it gets like the ClientID and then get every data from that connection and write it back to the client. Basically echoing the input. Then use a commandline to connect to your server from multiple windows for a test and that way you can develop and test your server in basic easy steps and learn how network communication with a server works.
You might need to install a telnet client for these tests if you develop it in windows. So you can use
Code: Select all
telnet localhost portnumber
Re: how can i "handle" socket server ?
Why would you need telnet when you have PB?
Just write your tests in PB.
You can easily stress out your server in very few lines.
Just write your tests in PB.
You can easily stress out your server in very few lines.
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum