[LINUX] Richten Sie einen UDP-Server in der Sprache C ein

Richten Sie einen Server in der Sprache C ein

Es ist schwierig, einen Server in der Sprache c einzurichten. Der Zweck dieses Artikels ist es, Neulingen und Personen, die noch nie einen Server geschrieben haben, zu ermöglichen, ihn vorerst zu verschieben und einige Fragen zu beantworten. Wenn Sie einen Server erstellen müssen und gerade arbeiten, können Sie Zeit sparen, indem Sie den folgenden Code kopieren und gemäß Ihren Geschäftsspezifikationen neu schreiben. Diesmal wird es in UDP sehr einfach sein. Ich denke, dies reicht möglicherweise nicht für die tatsächlichen Anforderungen. Es ist jedoch einfacher, sich vorwärts zu bewegen, wenn Sie verbunden sind, als wenn Sie überhaupt keine Hände oder Beine haben. Spielen Sie von hier aus mit dem Code, der Ihren Anforderungen entspricht. In diesem Artikel gibt es keine Erklärung dafür, was UDP ist. Es gibt so viele Erklärungen im Internet, dass sie faul sind. Bitte benutzen Sie diese. Für Bücher ist "Computer Network 5th Edition" gut, aber der Preis und die Dicke sind so ...

Umgebung

Ich werde die Umgebung, die ich vorerst ausprobiert habe, einsetzen, aber ich denke, dass sie mit relativ neuem Linux funktionieren wird.

Ubuntu 18.04.2 LTS
gcc 7.4.0

Einfacher UDP-Server

Aus Sicht der Implementierung kann UDP als einfaches TCP betrachtet werden.

Als einfacher Server

--Daten werden von localhost`` 9002 empfangen

Derzeit sieht der Code, der beim Kopieren und Einfügen funktioniert, folgendermaßen aus.

#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.Erstellen Sie eine Empfangsadresse
  struct addrinfo hints;
  memset (&hints, 0, sizeof (hints));
  hints.ai_socktype = SOCK_DGRAM;

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


  //2.Erstellen Sie einen Socket
  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.Binden Sie die lokale Adresse an den 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.Warten Sie auf die Clientverbindung
  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.Steckdose schließen
  close(socket_listen);
  printf ("Finished.\n");

  return 0;
}

Ein kleiner Kommentar

1. Erstellen Sie eine Empfangsadresse

Es gibt verschiedene Möglichkeiten, eine Verbindungsstruktur aufzubauen.

Dieses Mal habe ich es nach der dritten Methode gebaut.

Es gibt drei Aufgaben, um die Funktion "getaddrinfo" zu verwenden.

  1. Legen Sie die Empfangsadresse fest
  2. Legen Sie die empfangende Portnummer fest
  3. Definieren Sie einen Hinweis "addrinfo Struktur"

Die addrinfo Struktur in 3 setzt normalerweise ip4 oder ip6, TCP oder UDP. Wenn ip 0 ist, wird es zu ip4. SOCK_DGRAM ist ein Datagramm, und wenn es gesetzt ist, wird es UDP. Ich habe es diesmal nicht verwendet, aber der Rückgabewert der Funktion "getaddrinfo" ist errno. Wenn Sie es also richtig machen, sollten Sie es erhalten.

2. Erstellen Sie einen Socket

Dies ist derjenige, der mit solch einer vollständigen Gewohnheit schreibt, egal wer es tut. Ein Socket ist ein Kommunikationsterminal (in einem Programm), und das Betriebssystem sendet und empfängt über den Socket. Die "Socket-Funktion" erstellt einen Socket-Deskriptor. Ein Socket-Deskriptor ist eine Art Dateideskriptor. Ein Dateideskriptor ist eine eindeutige Nummer, mit der das Betriebssystem Dateien verarbeiten kann. Linux behandelt verschiedene Dinge als Dateien. Textdateien, Geräte (z. B. USB-Speicher) usw. In der Lage sein, wie Dateien im Netzwerk zu lesen und zu schreiben Dies ist die Rolle des Socket-Deskriptors. Der Rückgabewert der Socket-Funktion ist der Socket-Deskriptor.

3. Binden Sie die lokale Adresse an den Socket

Dies ist auch eine Gewohnheit. Verknüpfen Sie die von der Bindefunktion empfangene Adresse mit dem Socket. Jetzt sind Sie bereit zu empfangen.

4. Warten Sie, bis der Client eine Verbindung hergestellt hat

Der wichtigste Prozess. Ich bin sicher, wir werden hier in diesem Chan verschiedene Dinge tun. Normalerweise wird der Server nicht gelöscht, sodass er eine unbegrenzte Schleife aufweist. Verwenden Sie zum Empfangen die Funktion "recvfrom". Die Funktion "recvfrom" empfängt die Quellinformationen. Die sockaddr_storage Struktur ist eine Struktur, die entweder durch ip4 oder ip6 dargestellt werden kann.

5. Schließen Sie die Steckdose

Wie Speicher und Threads lecken Sockets, sodass Sie sie öffnen müssen. Die Funktion "Schließen" wird verwendet, um die Datei zu schließen. Da der Socket auch als Datei behandelt werden kann, kann er mit derselben Schließfunktion wie die Datei geöffnet werden.

Vorerst der Kunde

Ich habe das Gefühl, ich brauche es nicht. Ich lese die Verbindungsfunktion, obwohl es UDP ist. Tatsächlich können Sie die Verbindungsfunktion in UDP verwenden. Sie können auch mit der Verbindungsfunktion auf dem Server schreiben. Wenn Sie die Verbindungsfunktion in UDP verwenden, verhält sie sich anders als in TCP. Die Erklärung hier ist ... gut.

#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

Richten Sie einen UDP-Server in der Sprache C ein
Richten Sie mit Python 3 einen einfachen HTTPS-Server ein
Richten Sie einen Test-SMTP-Server in Python ein.
Richten Sie einen einfachen SMTP-Server in Python ein
Richten Sie in 30 Minuten einen kostenlosen Server unter AWS ein
Richten Sie mit Docker einen Samba-Server ein
Richten Sie mit Twisted einen Mailserver ein
Richten Sie einen einfachen HTTPS-Server mit Asyncio ein
Richten Sie einen lokalen Server mit Go-File-Upload ein.
Richten Sie einen lokalen Server mit Go-File-Download ein.
Richten Sie mit http.server in Python 3 in 30 Sekunden einen lokalen Webserver ein
So richten Sie einen lokalen Entwicklungsserver ein
Richten Sie eine Entwicklungsumgebung für die Verarbeitung natürlicher Sprache ein
Versuchen Sie, ein Python-Modul in C-Sprache zu erstellen
Richten Sie einen einfachen lokalen Server auf Ihrem Mac ein
Richten Sie einen Minecraft-Ressourcenserver (Spigot) über Docker (2) ein.
Richten Sie mit Samba einen Dateiserver unter Ubuntu 20.04 ein
[Teil 1] Lassen Sie uns einen Micra-Server unter Linux einrichten
Erstellen Sie einen Webserver in der Sprache Go (net / http) (1)
Richten Sie einen Minecraft-Ressourcenserver (Spigot) über Docker ein
[Vagrant] Richten Sie einen einfachen API-Server mit Python ein
Einbettung der Maschinensprache in die Sprache C.
Heap-Sortierung in C-Sprache
Richten Sie Nunjucks in Node.js ein
So zeigen Sie das Änderungsdatum einer Datei in C-Sprache bis zu Nanosekunden an
Ich möchte mit swagger-codegen in Sekundenschnelle einen Mock-Server für Python-Flask einrichten.
Richten Sie einen Webserver mit CentOS7 + Anaconda + Django + Apache ein
So richten Sie einen einfachen SMTP-Server ein, der lokal in Python getestet werden kann
Schreiben Sie einen tabellengesteuerten Test in C.
Modultest mit mehreren Instanzen in C-Sprache
Realisieren Sie die Schnittstellenklasse in der Sprache C.
ABC166 in Python A ~ C Problem
Löse ABC036 A ~ C mit Python
Erste Schritte mit SQLite in einer Programmiersprache
Löse ABC037 A ~ C mit Python
Segfo mit 16 Zeichen in C-Sprache
Einführung in die in C Language Part 1 Server Edition erlernte Socket-API
Einführung in die in C-Sprache gelernte Socket-API 4. UDP Server / Client Edition Nr. 1
Linkliste (list_head / queue) in C-Sprache
Löse ABC175 A, B, C mit Python
Richten Sie mit Python einen Dummy-SMTP-Server ein und überprüfen Sie den Sendevorgang von Action Mailer
Senden Sie E-Mails mit mailx an einen mit Python eingerichteten Dummy-SMTP-Server.
Richten Sie Pipenv auf Pycharm in einer Windows-Umgebung ein
Generieren Sie mit Python eine C-Sprache aus dem S-Ausdruck
Richten Sie einen Server ein, der mehrere Verbindungen gleichzeitig verarbeitet
Ich habe ein Modul in C-Sprache erstellt, das von Python geladene Bilder filtert
Erstellen Sie eine Entwicklungsumgebung für die C-Sprache mit einem Container
Verwenden Sie eine Skriptsprache für ein komfortables C ++ - Leben
Erstellen Sie eine Datei, die in der Skriptsprache ausgeführt werden kann
So steuern Sie Multiprozesse ausschließlich in C-Sprache
Legen Sie eine feste IP in der Linux-Umgebung fest
Rufen Sie Python-Skripte aus Embedded Python in C ++ / C ++ auf
Richten Sie eine Python-Entwicklungsumgebung auf Marvericks ein
Ich habe versucht, ein Python 3-Modul in C hinzuzufügen
Richten Sie einen Dateiserver mit Samba mit ZeroPi von Friendly Arm ein [Betriebssysteminstallation]
Richten Sie einen FTP-Server ein, der sofort erstellt und zerstört werden kann (in Python).
Richten Sie mit samba einen Dateiserver mit ZeroPi von Friendly Arm ein [Gekaufte Artikel]
Suchen Sie eine Richtlinie für die Anzahl der Prozesse / Threads, die auf dem Anwendungsserver festgelegt werden sollen