Delphi : How to send text to one specific client connected to the server socket knowing their local IP Address? -
i'm working on small text-based messaging platform on network class.
everything works, i'm trying implement private message function enter friend's ip , message, , gets sent server , able send message specific client related ip.
i have working, except i'm not able figure out how send text 1 specific client based on ip address. thought able temp2
string , msgip
target ip , msg
message:
for := 1 serversocket1.socket.activeconnections begin temp2:=serversocket1.socket.connections[i]; if temp2=msgip begin serversocket1.socket.connections[i].sendtext(msg); end; end;
there 3 mistakes in code:
the
connections[]
property uses 0-based indexes, loop using 1-based indexes. skip first connection, , crash trying access past last connection.the
connections[]
property returnstcustomwinsocket
object pointer, not string. need compare target ip string object'sremoteaddress
property value.you not breaking loop if find match.
try instead:
var client: tcustomwinsocket; begin := 0 serversocket1.socket.activeconnections-1 begin client := serversocket1.socket.connections[i]; if client.remoteaddress = msgip begin client.sendtext(msg); break; end; end; end;
now, said, know remoteaddress
remote client's ip server's perspective. if client connecting server through proxy or nat/router, remoteaddress
ip of proxy/nat, not client itself. multiple clients connected through same proxy/nat, have same remoteaddress
ip. if class assignment , there no proxy/nat involved, remoteaddress
may fine, provided don't have multiple instances of app running on same machine @ same time.
to uniquely identify specific client on server, regardlesss of how connected server, need use client's remoteaddress
and remoteport
property values together:
var client: tcustomwinsocket; begin := 0 serversocket1.socket.activeconnections-1 begin client := serversocket1.socket.connections[i]; if (client.remoteaddress = msgip) , (client.remoteport = msgport) begin client.sendtext(msg); break; end; end; end;
however, using ip+port not intuitive when 1 client wants communicate client, if not know each other's port values.
a better option have each client login server unique identifier, such username. can use client's tcustomwinsocket.data
property keep track of per-client data , compare needed, eg:
type tclientdata = record username: string; end; ... // during login... var clientdata: tclientdata; begin new(clientdata); clientdata.username := ...; // read client socket.data := clientdata; end; ... // during logout/disconnect... var clientdata: tclientdata; begin clientdata := socket.data; socket.data := nil; dispose(clientdata); end; ... // during private messaging var client: tcustomwinsocket; begin := 0 serversocket1.socket.activeconnections-1 begin client := serversocket1.socket.connections[i]; if tclientdata(client.data).username = msguser begin client.sendtext(msg); break; end; end; end;
this way, can send messages specific client regardless of located , how connected server. if client disconnects , reconnects, ip/port changes per connection. login identifier more consistent , easier work with.
Comments
Post a Comment