Sockets UDP en C

Je travaille sur un problème de devoirs en classe. Je veux démarrer un serveur UDP qui écoute une demande de fichier. Il ouvre le fichier et le renvoie au client demandeur avec UDP.

Heres le code du serveur.

// Create UDP Socket if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { perror("Can't create socket"); exit(-1); } // Configure socket memset(&server, 0, sizeof server); server.sin_family = AF_INET; // Use IPv4 server.sin_addr.s_addr = htonl(INADDR_ANY); // My IP server.sin_port = htons(atoi(argv[1])); // Server Port // Bind socket if ((bind(sockfd, (struct sockaddr *) &server, sizeof(server))) == -1) { close(sockfd); perror("Can't bind"); } printf("listener: waiting to recvfrom...\n"); if (listen(sockfd, 5) == -1) { perror("Can't listen for connections"); exit(-1); } while (1) { client_len = sizeof(struct sockaddr_in); newsockfd = accept(sockfd, (struct sockaddr*)&client,&client_len); if (newsockfd < 0) { perror("ERROR on accept"); } // Some how parse request // I do I use recv or recvfrom? // I do I make new UDP socket to send data back to client? sendFile(newsockfd, filename); close(newsockfd); } close(sockfd); 

Je suis un peu perdu, comment puis-je récupérer les données du client? Et comment puis-je établir une nouvelle connexion UDP avec le client?

Comment UDP est différent de TCP:

  • orienté message, pas orienté stream. Vous ne lisez pas / écrivez ou envoyez / recv. Vous envoyez / recvfrom. La taille du message est limitée à 64 Ko. Chaque appel à recvfrom reçoit un message envoyé par un appel à sendto. Si recvfrom passe un tampon plus petit que la taille du message, le rest du message est parti pour de bon.

  • pas de connexions. Par conséquent, pas d’écoute / acceptation / connexion. Vous envoyez un message à une adresse / un port particulier. Lorsque vous recevez un message (sur l’adresse / le port auquel votre socket est lié), vous obtenez la source du message entrant en tant que paramètre de sortie à recvfrom.

  • aucune garantie. Les messages peuvent être supprimés ou reçus dans le désordre. Si je me souviens bien, ils ne peuvent cependant pas être tronqués.

Un dernier mot de prudence – vous pouvez vous retrouver à réinventer TCP sur UDP. Dans ce cas, arrêtez et revenez à TCP.

J’ai écrit un client-serveur UDP en C , où le client envoie un numéro d’enregistrement et le serveur donne un nom comme retour.

SERVEUR

 0. Variable initialization 1. sock() 2. bind() 3. recvfrom() 4. sendto() 

CLIENT

 0. gethostbyname() 1. sock() 2. bzero() 4. sendto() 5. recvfrom() 

J’espère que ça aide. Vous pouvez trouver l’exemple de code ici serveur / client udp

accept est utilisé uniquement pour les sockets orientés connexion (STREAM). UDP n’est pas un stream, ni orienté, donc il n’y a pas de connexion et vous ne pouvez pas utiliser accept (2) – il retournera EOPNOTSUPP.

Au lieu de cela, vous venez de lire les paquets directement à partir du socket de service lié (en utilisant généralement recvfrom (2) afin de savoir d’où vient votre origine, bien que vous puissiez utiliser recv ou tout simplement lire si cela ne vous dérange pas), après quoi vous pouvez renvoyer des paquets en utilisant le même socket (et généralement en utilisant sendto (2))

Gardez à l’esprit qu’UDP est sans connexion. Il envoie uniquement des paquets et ne convient pas à l’envoi de fichiers, à moins que tout le contenu ne soit contenu dans un seul paquet UDP.

Si vous voulez quand même envoyer / recevoir des paquets UDP, vous appelez simplement sendto / recvfrom avec les adresses appropriées.