Page 1 of 1
Network library -- unique id's?
Posted: Thu Dec 15, 2011 12:37 am
by jassing
I am writing a client/server applet. This has the potential to receive info multiple times from the same IP in series ...
I'm finding that the EventClient() doesn't change each time the client disconnects.
for example:
a client connects to the server, the EventClient() is 3911160.
the client send some data to the server.
the client disconnects from the server
<wait a second>
the client re-connects to the server, the EventClient is (again) 3911160
is there a way to force the clientid to be new each time it connects?
Or is it up to me to create unique id's based on the client connecting?
Re: Network library -- unique id's?
Posted: Fri Dec 16, 2011 11:26 pm
by LuaDev
Hey is that you Josh ? (Its Riz from IR)
Anyway, how are you creating the client, are you using a global variable to store the ConnectionID?? (on client side)
Re: Network library -- unique id's?
Posted: Sat Dec 17, 2011 1:44 am
by Shield
The handle is probably re-used, so while a handle is guaranteed to be unique while it's
in use, there is no convention that prohibits any system from re-use them (which would be silly anyway).
If you need to associate data with a specific client you have to implement some kind of login mechanism,
as you probably want to associate information with a user and not with a machine anyway.
Re: Network library -- unique id's?
Posted: Sat Dec 17, 2011 2:01 am
by jassing
LuaDev wrote:Hey is that you Josh ? (Its Riz from IR)
Aye.
LuaDev wrote:Anyway, how are you creating the client, are you using a global variable to store the ConnectionID?? (on client side)
Global? no. it's a localized var to the function that does the communication. Take the two examples in the help file -- it's easily repeatable.
I finally got around the issue -- read on...
Shield wrote:The handle is probably re-used, so while a handle is guaranteed to be unique while it's in use, there is no convention that prohibits any system from re-use them (which would be silly anyway).
Right -- but I wanted to uniquely identify each connection and store data from the client with that unique id.
Shield wrote:If you need to associate data with a specific client you have to implement some kind of login mechanism, as you probably want to associate information with a user and not with a machine anyway.
What I needed was to store the information with the connection. Each connection comes from one or more machines sending text and files. no "user" to associate it with; besides, one user could then send from multiple machines (or multiple in the same machine) and I'd be right back to where I am.
How I did it.
I got around it by using a static map -- the map id is the hex() of the clientid. Each time a client
properly disconnects I increment the counter in the map. I consider then the "id" of the connection, not just the client id -- but the hex(clientid)+":" then append the value in the map var.
In this way; if a client is dropped (for whatever reason) the counter will not increment, so re-connecting right away, can re-establish the connection. IF the client reconnects promptly and the same clientid is used, I then can look up what was already transferred and tell the client to "skip ahead".
When it comes to processing the data, any client that didn't disconnect properly; the data is simply discarded.
I consider a connection properly disconnected if it issues the "bye" command. when the 'bye' is issued, i increment the counter, in that way; if another client connects it will get a new "id" for it's session. It's working well; but I understand, it probably wouldn't fit all situations.
Re: Network library -- unique id's?
Posted: Sat Dec 17, 2011 9:04 pm
by RichAlgeni
You could also store the IP address of the client connection:
And the readable version:
Code: Select all
IPString(GetClientIP(EventClient()))
Then use the map structure described above to save the data from each IP address.
Re: Network library -- unique id's?
Posted: Sat Dec 17, 2011 10:02 pm
by jassing
RichAlgeni wrote:You could also store the IP address of the client connection
This wouldn't account for multiple connections from the same IP -- I needed to have a unique identifier for the connection - something that would not repeat.
Re: Network library -- unique id's?
Posted: Sun Dec 18, 2011 11:48 am
by infratec
Hi jassing,
I found a solution: Use GetClientPort().
I used the modified example of the Help to test it:
Code: Select all
If InitNetwork() = 0
MessageRequester("Error", "Can't initialize the network !", 0)
End
EndIf
Port = 6832
*Buffer = AllocateMemory(1000)
If CreateNetworkServer(0, Port)
Debug "Server created (Port "+Str(Port)+")."
Repeat
SEvent = NetworkServerEvent()
If SEvent
ClientID = EventClient()
Debug GetClientPort(ClientID)
Select SEvent
Case #PB_NetworkEvent_Connect
Debug "A new client has connected !"
Case #PB_NetworkEvent_Data
Debug "Client "+Str(ClientID)+" has send a packet !"
ReceiveNetworkData(ClientID, *Buffer, 1000)
Debug "String: "+PeekS(*Buffer)
Case #PB_NetworkEvent_File
Debug "Client "+Str(ClientID)+" has send a file via the network !"
ReceiveNetworkFile(ClientID, "C:\TEST_Network.ftp3")
Case #PB_NetworkEvent_Disconnect
Debug "Client "+Str(ClientID)+" has closed the connection..."
EndSelect
EndIf
Until Quit = 1
CloseNetworkServer(0)
Else
Debug "Can't create the server (port in use ?)."
EndIf
If the client closes the connection the result is 0.
So you can delete this connection from a linked list or a map.
If the same IP connect again, the port is different.
Bernd
Re: Network library -- unique id's?
Posted: Sun Dec 18, 2011 12:12 pm
by infratec
Hi,
I think I would use something like this:
Code: Select all
#ConnectionClearTime = 3000
Structure ConnectionStr
LastReceiveTime.i
PacketCounter.i
EndStructure
NewMap Connection.ConnectionStr()
If InitNetwork() = 0
Debug "Can't initialize the network !"
End
EndIf
Port = 6832
*Buffer = AllocateMemory(1000)
OpenWindow(0, 0, 0, 0, 0, "", #PB_Window_Invisible)
AddWindowTimer(0, 1, #ConnectionClearTime)
If CreateNetworkServer(0, Port)
Debug "Server created (Port "+Str(Port)+")."
Repeat
If WindowEvent() = #PB_Event_Timer
If EventTimer() = 1
Time = ElapsedMilliseconds()
ForEach Connection()
If Time - Connection()\LastReceiveTime > #ConnectionClearTime
DeleteMapElement(Connection())
EndIf
Next
EndIf
EndIf
SEvent = NetworkServerEvent()
If SEvent
ClientID = EventClient()
ClientPort = GetClientPort(ClientID)
Debug "Active connections: " + Str(MapSize(Connection()))
Select SEvent
Case #PB_NetworkEvent_Connect
Debug "A new client has connected !"
AddMapElement(Connection(), RSet(Str(ClientID), 10) + Str(ClientPort))
Connection()\LastReceiveTime = ElapsedMilliseconds()
Connection()\PacketCounter = 0
Case #PB_NetworkEvent_Data
Debug "Client "+ Str(ClientID) +" has send a packet !"
ReceiveNetworkData(ClientID, *Buffer, 1000)
Debug "String: "+PeekS(*Buffer)
If FindMapElement(Connection(), RSet(Str(ClientID), 10) + Str(ClientPort))
Connection()\LastReceiveTime = ElapsedMilliseconds()
Connection()\PacketCounter + 1
Debug "Received now " + Str(Connection()\PacketCounter) + " packets from this connection"
EndIf
Case #PB_NetworkEvent_File
Debug "Client "+Str(ClientID)+" has send a file via the network !"
ReceiveNetworkFile(ClientID, "C:\TEST_Network.ftp3")
If FindMapElement(Connection(), RSet(Str(ClientID), 10) + Str(ClientPort))
Connection()\LastReceiveTime = ElapsedMilliseconds()
EndIf
Case #PB_NetworkEvent_Disconnect
Debug "Client "+ Str(ClientID) + " has closed the connection..."
EndSelect
EndIf
Until Quit = 1
CloseNetworkServer(0)
Else
Debug "Can't create the server (port in use ?)."
EndIf
I add a connection to a map with the port included in the key.
Each time the same connection send something, I set the receivetime.
After a defined time without receiving something from this connection, I clear it from the map.
Hope that's what you need.
Bernd
P.S.: I used this codes to test it:
Client1.pbCode: Select all
If InitNetwork() = 0
Debug "Can't initialize the network !"
End
EndIf
Port = 6832
ConnectionID = OpenNetworkConnection("127.0.0.1", Port)
If ConnectionID
SendNetworkString(ConnectionID, "An hello from a client !!! :-)")
CloseNetworkConnection(ConnectionID)
Else
Debug "Can't find the server (Is it launched ?)."
EndIf
Client2.pbCode: Select all
If InitNetwork() = 0
Debug "Can't initialize the network !"
End
EndIf
Port = 6832
ConnectionID = OpenNetworkConnection("127.0.0.1", Port)
If ConnectionID
For i = 1 To 20
SendNetworkString(ConnectionID, "An hello " + Str(i) + " from a client !!! :-)")
Delay(1000)
Next i
CloseNetworkConnection(ConnectionID)
Else
Debug "Can't find the server (Is it launched ?)."
EndIf
Re: Network library -- unique id's?
Posted: Sun Dec 18, 2011 6:33 pm
by jassing
The problem with port is:
if a client connects, completes an exchange; closes the connection. Then 10 minutes later, re-connects, the port used could be the same; resulting in a non-unique "id".
Re: Network library -- unique id's?
Posted: Sun Dec 18, 2011 7:06 pm
by infratec
Hi,
first, I don't think that the port is the same after 10 minutes.
Second, that's the reason for 'clearing' the connection after a fixed time.
Have a look on note 1
http://en.wikipedia.org/wiki/Ephemeral_port
Bernd