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:

  1. the connections[] property uses 0-based indexes, loop using 1-based indexes. skip first connection, , crash trying access past last connection.

  2. the connections[] property returns tcustomwinsocket object pointer, not string. need compare target ip string object's remoteaddress property value.

  3. 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