Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
TIdTcpServer mixing clients
#1
Hi all

We are running TIdTcpServer on a cloud server. Usually all clients connect from the same local network. So their remote IP addresses seems to be the same at the server side. Sometimes sending message from server change clients. So message sent to client A has gone to client B. It happens maybe once per about 1000 messages but still too often. Usually it happens when there is very short interval between client messages. Still socket handle, remote port and other client specific information remains correct.

Server program has been made with Rad Studio C++ 10.3 and it's Indy library.

Anybody noticed the same feature?


Henschen
Reply
#2
There is nothing in Indy that would confuse clients and send data to the wrong one. Socket identification is based on more than ip and port once it is opened and uses a handle instead.

The dispatching error is somewhere in your code or you have memory corruption caused by user code.
Reply
#3
(12-17-2018, 04:21 PM)henschen Wrote: We are running TIdTcpServer on a cloud server. Usually all clients connect from the same local network. So their remote IP addresses seems to be the same at the server side.

If the clients have to pass through a proxy/router to reach your server, then yes, the server would see the same IP for all of them, but different ports.

(12-17-2018, 04:21 PM)henschen Wrote: Sometimes sending message from server change clients. So message sent to client A has gone to client B. It happens maybe once per about 1000 messages but still too often. Usually it happens when there is very short interval between client messages. Still socket handle, remote port and other client specific information remains correct.

How are you determining which client to send a given message to? The client's IP address alone is not unique enough for identification purposes. At the very least, you would need to use the client's IP and port. Though, that pair can be reused when a client disconnects and a new client connects. Same with a socket handle. Such things are only unique for the lifetime of a connection, and can then be reused once the connection is gone.

You may need to require your clients to explicitly login to the server using a unique identifier, such as a username. Maybe also send the client's local LAN IP as well. You can manually keep track of such values inside of the TIdContext object of each connection, either by:

- using the TIdContext.Data property

- deriving a new class from TIdServerContext to add whatever properties you want, then assign that class to the TIdTCPServer.ContextClass property, and then type-cast TIdContext object pointers when needed.

Reply
#4
Clients are identified with MAC address. Every client has its own log file. There are following successive lines in the code.

Code:
// 1. Write socket handle to log file.
LogMessage(AnsiString().sprintf("Handle %X", IdContext->Binding->Handle));
// 2. Write message data (TIdByte ByteArray) to log file.
LogData(ByteArray);
// 3. Send message
IdContext->Connection->IOHandler->Write(ByteArray, ByteArray.Length, 0);

1. Socket handle never changes.
2. Message data is correct. It is unique to client.
3. Third line sends message occasionally to wrong client.

henschen
Reply
#5
(12-18-2018, 06:21 PM)henschen Wrote: Clients are identified with MAC address.

How is your server obtaining each client's MAC? That is not something it can query from the connected TCP sockets. Are the clients sending their own MACs to the server after connecting to it? How does each client obtain the MAC it is using to connect with (a PC/device may have multiple network interfaces, and thus multiple MACs). Have you verified that on the server side, you are not accidentally tracking multiple clients with the same MAC? Since a MAC and IP are closely related, multiple clients connecting from the same PC/device would have not only the same IP, but also the same MAC, too.

(12-18-2018, 06:21 PM)henschen Wrote: Every client has its own log file.

How are you determining the log filename for each client? Are you sure multiple clients are not simply logging to the same file?

(12-18-2018, 06:21 PM)henschen Wrote: 1. Socket handle never changes.

Not for an individual client, no. Its socket handle is consistent for the lifetime of its connection. But multiple clients connected concurrently have unique socket handles. And like I said earlier, once a given client disconnects and its socket handle is closed, the OS is free to reuse that same handle for a new client socket afterwards.

(12-18-2018, 06:21 PM)henschen Wrote: 3. Third line sends message occasionally to wrong client.

Based on what you have described, the only way I can see can happening is if you are manually dipping into the TIdTCPServer.Contexts list to choose a target TIdContext to send to, and are choosing the wrong client at times. What does that code actually look like? What is your criteria for choosing the target client? I'm assuming that since you are tracking client MACs, one client (or the server itself) can opt to send a message to a specific client's MAC, is that right?

Within the server's OnConnect/OnExecute/OnDisconnect events, the provided TIdContext parameter is unique to each client. If you send the message to the same TIdContext that fires the event, there is no possibility for cross-over with another client.

Reply
#6
Thank you for your answers. I try to debug our code more carefully.

henschen
Reply


Forum Jump:


Users browsing this thread: 2 Guest(s)