Analyse récapitulative des protocoles UDP open source et fiables

Exigences du projet : Utiliser le protocole UDP pour transférer les données vidéo (environ 30 Mo/sec) vers le PC directement connecté à l'appareil avec le plus de précision possible. Les données erronées sont directement rejetées. Information donnée par le patron : UDP ne sera pas hors service
car il n'est pas Les gens brouilleront délibérément les données. Puisque les données sont envoyées à la carte réseau dans l'ordre, elles doivent bien sûr être dans l'ordre. Le
résultat réel de la mesure : les paquets de données UDP doivent être désordonnés.
Parce que c'est l'une des caractéristiques d'UDP . D'un point de vue philosophique, c'est Si une certaine caractéristique n'est pas maintenue, elle n'apparaîtra certainement pas.
Selon l'explication, si un système chaotique n'est pas standardisé et trié, le système évoluera inévitablement dans le sens d'une augmentation entropie, c'est-à-dire dans le sens de devenir de plus en plus chaotique.

Une autre caractéristique de crash d'UDP , en plus du désordre, est l'inaccessibilité des données, c'est-à-dire qu'il n'y a aucune garantie que toutes les données seront livrées. Une autre caractéristique
est : La fragmentation UDP est généralement limitée à 1400 (le maximum est 1476, mais à soyez prudent, 1 400 est une valeur empirique).
Par conséquent, toutes les données doivent être fragmentées manuellement ; du côté de la réception, elles doivent être assemblées en conséquence.

À l'heure actuelle, une question se pose. Puisque l'utilisation d'UDP nécessite un partitionnement et garantit l'exactitude, pourquoi ne pas utiliser TCP directement ? C'est une
bonne question.
La réponse est que le projet doit nécessiter l'utilisation d'UDP .
L'un des avantages est que le serveur peut continuer à envoyer des données à une certaine adresse sans savoir que le client existe ou a été démarré. C'est quelque chose que TCP ne peut pas faire. À propos, la vitesse théorique d'UDP est légèrement supérieure à celle de TCP, mais cette promotion, pour une implémentation
complexe logique, je préférerais pas...

Après avoir essayé de réinventer la roue moi-même et essayé pendant un demi-mois d'utiliser le protocole UDP pour créer un protocole de transmission fiable, la réalité m'a frappé durement. La question est donc : pourquoi ne pas utiliser une bibliothèque
similaire existante pour le faire ?
Je dois créer respectivement le serveur et le client du côté intégré et du côté VS studio du PC. Les bibliothèques générales, C++ sous Windows peuvent convenir, mais il n'y a pas de code intégré correspondant, ni de certains fichiers h spécifiques à Windows, ce qui fait qu'il ne peut pas être transplanté. De plus, certaines bibliothèques sont énormes en taille et coûteuses à apprendre. Ce qui est plus fatal, c'est qu'il n'est pas sûr qu'après avoir passé du temps, la bibliothèque sera capable de fonctionner normalement. Le temps du projet ne le permet pas.

Cependant, à la fin, j'ai honnêtement analysé plusieurs bibliothèques bien connues et analysé clairement les avantages et les inconvénients. Finalement, ENet a été adopté .
Les résultats de la recherche seront partagés ci-dessous.

nom adresse langage principal Poids léger? Caractéristiques et avantages
RakNet https://github.com/facebookarchive/RakNet C C++ HTML plus lourd
DEHORS https://sourceforge.net/projects/udt/ C++ plus léger
asio2 https://github.com/zhllxt/asio2 C++C plus léger Seuls les fichiers h conviennent à la transplantation
KCP https://github.com/skywind3000/kcp C-C++ très léger Il n'y a que 4 fichiers principaux, principalement utilisés pour améliorer le problème de retard de TCP et UDP
UDP fiable d'ENET http://enet.bespin.org/index.html C++ plus léger Fiable et non fiable sont facultatifs. Ce sont deux concepts de homologue, et il n'y a pas de serveur et de client clairs.

Vous pouvez également télécharger le code source ici
https://github.com/lsalzman/enet

C'est un très bon exemple sur YouTube. Vous pouvez suivre ses 2 premiers chapitres pour implémenter un serveur et un client communicables simples. La
série de tutoriels Basic ENet - Configuration serveur/client (1/5)
est donnée sur leur site officiel. Le code
https:/ /usergames.net/tutorials/enet/part1
est comme ça, vous pouvez le copier directement pour référence.


/* ./server/main.c */

#include <stdio.h>
#include <enet/enet.h>

int main (int argc, char ** argv)
{
    
    
    if (enet_initialize () != 0)
    {
    
    
        fprintf (stderr, "An error occurred while initializing ENet.\n");
        return EXIT_FAILURE;
    }
    atexit (enet_deinitialize);

ENetEvent event;
ENetAddress address;
ENetHost* server;

/* Bind the server to the default localhost.     */
/* A specific host address can be specified by   */
/* enet_address_set_host (& address, "x.x.x.x"); */
address.host = ENET_HOST_ANY; // This allows
/* Bind the server to port 7777. */
address.port = 7777;



server = enet_host_create (&address	/* the address to bind the server host to */,
				32	/* allow up to 32 clients and/or outgoing connections */,
				1	/* allow up to 1 channel to be used, 0. */,
				0	/* assume any amount of incoming bandwidth */,
				0	/* assume any amount of outgoing bandwidth */);

if (server == NULL)
{
    
    
	printf("An error occurred while trying to create an ENet server host.");
	return 1;
}

// gameloop
while(true)
{
    
    
	ENetEvent event;
	/* Wait up to 1000 milliseconds for an event. */
	while (enet_host_service (server, & event, 1000) > 0)
	{
    
    
		switch (event.type)
		{
    
    
			case ENET_EVENT_TYPE_CONNECT:
				printf ("A new client connected from %x:%u.\n",
		  		event.peer -> address.host,
				event.peer -> address.port);
			break;

			case ENET_EVENT_TYPE_RECEIVE:
				printf ("A packet of length %u containing %s was received from %s on channel %u.\n",
					event.packet -> dataLength,
					event.packet -> data,
					event.peer -> data,
					event.channelID);
					/* Clean up the packet now that we're done using it. */
					enet_packet_destroy (event.packet);
			break;

			case ENET_EVENT_TYPE_DISCONNECT:
				printf ("%s disconnected.\n", event.peer -> data);
				/* Reset the peer's client information. */
				event.peer -> data = NULL;
		}
	}
}

enet_host_destroy(server);

return 0;
}

Quelques références :

L'exemple que m'a donné le professeur He
https://blog.csdn.net/yuanchunsi/article/details/70244338

https://usergames.net/tutorials/enet/part1
API
http://enet.bespin.org/enet_8h.html
Tutoriel
http://enet.bespin.org/Tutorial.html
Traduction du didacticiel ENet
https://www. cnblogs.com/allen8807/archive/2010/12/10/1900473.html

おすすめ

転載: blog.csdn.net/scarlettsp/article/details/122307952