1

I have TCP server and clients written in C#. Since my connection is over wifi which is not reliable, I use resending the same packet and handle packet loss.

For example a bank account platform. The user deposites money and the client send this message to the server, if the server received this message, it will reply the client the operation is successful. If the client doesnt receive the reply, it will send again after a period of time.

This looks simple but I faced a situation when the wifi stucks and the client didnt receive reply and keep sending the same message to the server. End up those messages were received by the server at the same time. As a result the server thought the user deposites money 100 times.

I would like to know usually how people handle such case for tcp server client program, especially when the application is not just a chat application, but more sensitive information like money. My first thought is adding a transaction ID in the message so the server will not handle the messages with the same transaction ID, which will prevent the above case. But not sure if there is any better solution or .Net has some internal function for this.

Thank you.

oleksii
  • 35,458
  • 16
  • 93
  • 163
AkariKamigishi
  • 277
  • 7
  • 23

1 Answers1

0

When you code in C#, you are mostly working from within the Application layer of OSI model. TCP protocol works on the Transport layer (which is below the application layer).

Reliability, that you want to achieve, is already embedded inside the TCP protocol itself. This means, it will attempt to resent the packets, if some were lost, automatically without your additional requests. This will also happen before control is returned to the application layer program. There are also other guarantees, such as ordered delivery of the packets.

This means, that the functionality you need is already implemented at the layers bellow and you don't need to worry about it.

Note, if you were to use UDP, you would need to handle reliability problems yourself.

oleksii
  • 35,458
  • 16
  • 93
  • 163
  • So do u mean the case that I received those 100 messages at the same time is the work by C# for which it helped me to resend those messages? – AkariKamigishi Oct 10 '13 at 13:56
  • The reason why I implemented the resending message function is because when I was testing the program, there is some errors occured on the server side program so I closed it and re-executed it. As a result the client program stucked as it didnt receive the reply and keep waiting. Or even simply the computer that running the server program is closed accidently and is needed to restart. How should I handle those case if I dont use my resending message function? – AkariKamigishi Oct 10 '13 at 14:00
  • @AkariKamigishi sorry was away. The protocol provides sufficient guarantees that a message is delivered. What you need to handle is the specific errors that you see on client or server side. Timeout is a common application level technique - when remote application cannot be reached, originator shall define and handle a timeout. – oleksii Oct 13 '13 at 18:52
  • @If computer is down you should define a timeout, which is generally available in all default communication calls. If a `send(data, timeout)` times out, it will throw a `TimeoutException` and you can handle it according to business logic, for example resend data in 1 minute with 5 attempts, if unsuccessful terminate. TCP protocol ensures that a message is delivered only once, if it cannot be delivered it dies first and only then you receive a notification that host cannot be reached. So don't worry about the low level stuff, work on the application level errors – oleksii Oct 13 '13 at 18:56
  • Application level errors include: timeouts, transaction commit/rollback, host is down for some short time (couple of minutes) – oleksii Oct 13 '13 at 18:58