[LINUX] Configurer un serveur UDP en langage C

Configurer un serveur en langage C

Il est difficile de mettre en place un serveur en langage c. Le but de cet article est de permettre aux nouveaux arrivants et aux personnes qui n'ont jamais écrit de serveur de le déplacer pour le moment et de répondre dans une certaine mesure à quelques questions. Si vous devez créer un serveur et travaillez actuellement, vous pouvez gagner du temps en copiant le code ci-dessous et en le réécrivant selon les spécifications de votre entreprise. Cette fois, ce sera très simple en UDP. Je pense que cela peut ne pas être suffisant pour les besoins réels. Cependant, il est plus facile d'avancer lorsque vous êtes connecté que lorsque vous n'avez ni mains ni jambes. À partir de là, jouez avec le code qui correspond à vos besoins. Il n'y a aucune explication dans cet article sur ce qu'est UDP. Il y a tellement d'explications sur Internet qu'elles sont pourries, alors veuillez les utiliser. Pour les livres, «Computer Network 5th Edition» est bon, mais le prix et l'épaisseur sont si ...

environnement

Je vais mettre l'environnement que j'ai essayé pour le moment, mais je pense qu'il fonctionnera avec des linux relativement récents.

Ubuntu 18.04.2 LTS
gcc 7.4.0

Serveur UDP simple

Du point de vue de la mise en œuvre, UDP peut être considéré comme un simple TCP.

En tant que simple serveur

Pour le moment, le code qui fonctionne si vous le copiez et le collez ressemble à ceci.

#include <ctype.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
#include <errno.h>

#include <stdio.h>
#include <string.h>

int main ()
{
  //1.Créer une adresse de réception
  struct addrinfo hints;
  memset (&hints, 0, sizeof (hints));
  hints.ai_socktype = SOCK_DGRAM;

  struct addrinfo *bind_address;
  getaddrinfo ("localhost", "9002", &hints, &bind_address);


  //2.Créer une prise
  int  socket_listen;
  socket_listen = socket (bind_address->ai_family,
              bind_address->ai_socktype,
              bind_address->ai_protocol);
  if (socket_listen < 0)
  {
      fprintf (stderr, "socket() failed. (%d)\n", errno);
      return 1;
  }


  //3.Liez l'adresse locale au socket
  if (bind (socket_listen, bind_address->ai_addr, bind_address->ai_addrlen))
  {
      fprintf (stderr, "bind() failed. (%d)\n", errno);
      return 1;
  }
  freeaddrinfo (bind_address);


  //4.Attendez la connexion client
  while (1)
  {
      struct sockaddr_storage client_address;
      socklen_t client_len = sizeof (client_address);

      char read[4096];
      memset(read, 0, sizeof(read));
      int bytes_received = recvfrom (socket_listen, read, 4096, 0,
                     (struct sockaddr *) &client_address,
                     &client_len);
      if (bytes_received < 1)
      {
        fprintf (stderr, "connection closed. (%d)\n", errno);
        return 1;
      }
      printf("receiving: %s", read);
  }

  //5.Fermer la prise
  close(socket_listen);
  printf ("Finished.\n");

  return 0;
}

Un petit commentaire

1. Créez une adresse de réception

Il existe plusieurs façons de créer une structure de connexion.

Cette fois, je l'ai construit par la troisième méthode.

Il y a trois tâches pour utiliser la fonction getaddrinfo.

  1. Décidez de l'adresse de réception
  2. Décidez du numéro de port de réception
  3. Définissez un indice ʻaddrinfo structure`

La «structure addrinfo» en 3 définit généralement ip4 ou ip6, TCP ou UDP. Si ip vaut 0, il devient ip4. SOCK_DGRAM est un datagramme, et lorsqu'il est défini, il devient UDP. Je ne l'ai pas utilisé cette fois, mais la valeur de retour de la fonction getaddrinfo est errno, donc si vous le faites correctement, vous devriez la recevoir.

2. Créez un socket

C'est celui qui écrit avec une habitude aussi complète, peu importe qui le fait. Un socket est un terminal de communication (sur un programme), et le système d'exploitation envoie et reçoit via le socket. La fonction socket crée un descripteur de socket. Un descripteur de socket est un type de descripteur de fichier. Un descripteur de fichier est un numéro unique qui permet au système d'exploitation de gérer les fichiers. linux traite diverses choses comme des fichiers. Fichiers texte, périphériques (comme une clé USB), etc. Pour pouvoir lire et écrire sur le réseau de la même manière que des fichiers C'est le rôle du descripteur de socket. La valeur de retour de la fonction socket est le descripteur de socket.

3. Liez l'adresse locale au socket

C'est aussi une habitude. Associez l'adresse reçue par la fonction de liaison au socket. Vous êtes maintenant prêt à recevoir.

4. Attendez que le client se connecte

Le processus le plus important. Je suis sûr que nous allons faire diverses choses ici dans ce chan. Normalement, le serveur n'est pas abandonné, donc il boucle indéfiniment. Utilisez la fonction recvfrom pour recevoir. La fonction recvfrom reçoit les informations source. La structure sockaddr_storage est une structure qui peut être représentée par ip4 ou ip6.

5. Fermez la prise

Comme la mémoire et les threads, les sockets fuient, vous devez donc les ouvrir. La fonction de fermeture est utilisée pour fermer le fichier. Puisque le socket peut également être traité comme un fichier, il peut être ouvert avec la même «fonction de fermeture» que le fichier.

Pour le moment, le client

J'ai l'impression que je n'en ai pas besoin. Je lis la fonction de connexion même si c'est UDP. En fait, vous pouvez utiliser la fonction de connexion dans UDP. Vous pouvez également écrire à l'aide de la fonction de connexion sur le serveur. Lorsque vous utilisez la fonction de connexion dans UDP, elle se comporte différemment lorsque vous l'utilisez dans TCP. L'explication ici est ... eh bien.

#include <ctype.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
#include <errno.h>

#include <stdio.h>
#include <string.h>

int main(void)
{
    struct addrinfo hints;
    memset(&hints, 0, sizeof(hints));
    hints.ai_socktype = SOCK_DGRAM;
    struct addrinfo *peer_addr;

    if(getaddrinfo("localhost","9002",&hints, &peer_addr))
    {
        fprintf(stderr, "getaddrinfo() failed. (%d)\n", GETSOCKETERRNO());
        return 1;
    }

    char addrbuf[100];
    char servbuf[100];
    getnameinfo(peer_addr->ai_addr, peer_addr->ai_addrlen, addrbuf, sizeof(addrbuf), servbuf, sizeof(servbuf), NI_NUMERICHOST);
    printf("%s %s\n", addrbuf, servbuf);

    puts("Creating socket");
    int socket_peer;
    socket_peer = socket(peer_addr->ai_family, peer_addr->ai_socktype, peer_addr->ai_protocol);
    if(!ISVALIDSOCKET(socket_peer))
    {
        fprintf(stderr, "socket() failed. (%d)\n", GETSOCKETERRNO());
        return 1;
    }

    if(connect(socket_peer,peer_addr->ai_addr, peer_addr->ai_addrlen))
    {
        fprintf(stderr,"connect() failed. (%d).\n", GETSOCKETERRNO());
        return 1;
    }

    freeaddrinfo(peer_addr);

    puts("Connected");

    while(1)
    {

        {
            char read[4096];
            if(!fgets(read, 4096, stdin)) break;

            int bytes = send(socket_peer, read, strlen(read), 0);
            printf("send %d bytes\n", bytes);
        }

    }
    puts("Closing socket");
    CLOSESOCKET(socket_peer);
    return 0;
}

Recommended Posts

Configurer un serveur UDP en langage C
Configurer un serveur HTTPS simple avec Python 3
Configurez un serveur SMTP de test en Python.
Configurer un serveur SMTP simple en Python
Configurez un serveur gratuit sur AWS en 30 minutes
Configurer un serveur Samba avec Docker
Configurer un serveur de messagerie avec Twisted
Configurer un serveur HTTPS simple avec asyncio
Configurer un serveur local avec le téléchargement Go-File-
Configurer un serveur local avec le téléchargement Go-File-
Configurez un serveur Web local en 30 secondes en utilisant http.server en python 3
Comment configurer un serveur de développement local
Mettre en place un environnement de développement pour le traitement du langage naturel
Essayez de créer un module Python en langage C
Configurer un serveur local simple sur votre Mac
Configurer un serveur de ressources Minecraft (Spigot) via docker (2)
Configurer un serveur de fichiers sur Ubuntu 20.04 à l'aide de Samba
[Partie 1] Configurons un serveur Micra sur Linux
Créer un serveur Web en langage Go (net / http) (1)
Configurer un serveur de ressources Minecraft (Spigot) via docker
[Vagrant] Configurer un serveur API simple avec python
Intégration du langage machine en langage C
Tri de tas fait en langage C
Configurer Nunjucks dans Node.js
Comment afficher la date de modification d'un fichier en langage C jusqu'à nanosecondes
Je veux configurer un serveur fictif pour python-flask en quelques secondes en utilisant swagger-codegen.
Configurer un serveur Web avec CentOS7 + Anaconda + Django + Apache
Comment configurer un serveur SMTP simple qui peut être testé localement en Python
Ecrire un test piloté par table en C
Test de module multi-instance en langage C
Réaliser une classe d'interface en langage C
ABC166 en Python A ~ C problème
Résoudre ABC036 A ~ C avec Python
Démarrez avec SQLite dans un langage de programmation
Résoudre ABC037 A ~ C avec Python
Segfo avec 16 caractères en langage C
Introduction à l'API Socket apprise en langage C, partie 1, édition serveur
Introduction à l'API Socket apprise en langage C 4e édition serveur / client UDP # 1
Liste de liens (list_head / queue) en langage C
Résoudre ABC175 A, B, C avec Python
Configurer un serveur SMTP factice avec Python et vérifier le fonctionnement de l'envoi depuis Action Mailer
Envoyez du courrier avec mailx à un serveur SMTP factice configuré avec python.
Configurer Pipenv sur Pycharm dans un environnement Windows
Générer un langage C à partir d'une expression S avec Python
Configurer un serveur qui traite plusieurs connexions en même temps
J'ai fait un module en langage C qui filtre les images chargées par Python
Créer un environnement de développement de langage C avec un conteneur
Utilisez un langage de script pour une vie confortable en C ++
Créer un fichier qui peut être exécuté dans le langage de script
Méthode de contrôle exclusive multi-processus en langage C
Définir une adresse IP fixe dans l'environnement Linux
Appel de scripts Python à partir de Python intégré en C ++ / C ++
Configurer un environnement de développement Python sur Marvericks
J'ai essayé d'ajouter un module Python 3 en C
Configurer un serveur de fichiers en utilisant samba avec ZeroPi de Friendly Arm [installation du système d'exploitation]
Mettre en place un serveur FTP qui peut être créé et détruit immédiatement (en Python)
Configurer un serveur de fichiers utilisant la samba avec ZeroPi de Friendly Arm [Articles achetés]
Trouvez une ligne directrice pour le nombre de processus / threads à définir sur le serveur d'applications