You can't create an application in a way it's not vulnerable to MiTM attacks because these attacks happen an a lower layer than your application works on. You can only secure the network which is used by the clients. There are several countermesures available. First you need port security which will prevent many of these attacks. Then you could add a net based IDS/IPS which is capturing the monitor port of your switch. But all of this wont come for free it will cost you some money and a lot of time.
The more practical solution is to use encryption to ensure that someone who performs a MiTM attack isn't able to read the data he captures. But even this won't give you 100% security. The main problem here is that you dont have a server.
Async encription (SSH like)
On both sides you create a RSA key pair and then use this to encrypt and decrypt messages. When the first connection is established between two hosts you save the key of that host to identifiy this host in further sessions. The problem here is that a MiTM-Attacker might interrupt the first session. He is then in a position where he can inject his own certificates to perform a MiTM attack anyway. This will also lead to a sitiuation where in further sessions that aren't interrupted by the attacker the connection will be recognized as insecure because the saved key of the opossing host is in fact the one of the attacker.
Your problem her is that you don't know the key of the opossing side until you connect for the first time. Many companies solve this issue when it comes to ssh by syncing the
ssh_known_hosts via a trustworthy server. You dont have such server because of that you can't do this here and you are kind of insecure at the first connection.
You can implement encryption with a pre-shared-key but the problem here is always the useability and the user behaviour. When you generate a PSK for every connection then the key must be exchanged. Always remember: People are lazy. They will send the PSK via mail which is potentially unencrypted. Also many people might say "ohh thats to complex I will use another software that is easy to use" and this is how people end up with easy to use but totally insecure software.
// Also none of the described proceedures will prevent a MiTM-Attack they will only prevent the attack from being successful in the way it was ment to be.