Programmation Socket en C dans Ubuntu

J’apprends le programme socket dans Ubuntu pour lequel j’ai écrit le programme suivant pour la communication client serveur. Le programme n’ouvre pas les ports. J’ai aussi d’autres questions concernant les communications client serveur:

  • Lorsque le serveur accepte la demande du client, le serveur commence-t-il à lire à partir du client au moment où il accepte la demande?
  • Le descripteur de fichier est-il renvoyé par u_connect et u_accept () identiques? (Je n’ai pas pu le trouver car mes ports ne s’ouvrent pas)
  • Puis-je utiliser un nombre aléatoire comme port puisque je teste la conversation du client sur le même ordinateur?

J’utilise une bibliothèque d’encapsulation qui contient les fonctions du système d’exploitation pour la programmation des sockets.

Voici le code:

Serveur.c

int main() { char client[50]; char buf[1024]; u_port_t portnumber; portnumber = 4862; int fd = u_open(portnumber); int communFd = u_accept(fd, client, 50); printf("Opened com %d\n\n", communFd); fprintf(stderr, "\nComun fd is %d\n\n\n", communFd); read(communFd, buf, 1024); write(STDOUT_FILENO, buf, 1024); fprintf(stderr, "\n\nReading complete\n"); return 0; } 

Client.c

 int main() { u_port_t portnumber; portnumber = 4862; char client[] = "Alfred"; char buf[1024]; int communFd = u_connect(portnumber, client); printf("comun is %d\n", communFd); read(STDIN_FILENO, buf, 1024); write(communFd, buf, 1024); return 0; } 

Lorsque le serveur accepte la demande du client, le serveur commence-t-il à lire à partir du client au moment où il accepte la demande?

Le serveur peut lire lorsque les données envoyées par le client (via write ()) sont reçues et disponibles dans le tampon de lecture de socket.

Le descripteur de fichier est-il renvoyé par u_connect et u_accept () identiques? (Je n’ai pas pu le trouver car mes ports ne s’ouvrent pas)

Non, même si les côtés serveur et client s’exécutent dans le même processus.

Puis-je utiliser un nombre aléatoire comme port puisque je teste la conversation du client sur le même ordinateur?

Vous pouvez lier sur un port de 0 à 65535. Les known ports de 0 à 1024 sont appelés known ports et sont déjà affectés à des services spécifiques par l’ IANA . Ma suggestion est d’utiliser un numéro de port dans la plage 49152-65535 mais personne ne vous interdit de l’utiliser une valeur faible.

Si le port est lié par un autre processus, il retournera un code d’erreur. Essayez avec un autre

C’est faux.

 read(communFd, buf, 1024); write(STDOUT_FILENO, buf, 1024); 

Vous devriez le faire à la place:

 ssize_t r; size_t space_left = 1024 while ((r=read(communFd, buf, space_left))>0) { space_left-=r; write(STDOUT_FILENO,buf,r); } 

Parce que ce qui est envoyé en une seule écriture peut être fragmenté sur le réseau et être extrait avec de nombreuses lectures.

Tout d’abord, je déconseille d’utiliser ce wrapper car il utilise des techniques assez archaïques. Je suggère de lire sur getaddrinfo , lier , écouter , recv , envoyer et fermer et lancer votre propre code de socket POSIX. Vous comprendrez beaucoup mieux. Je suggère également de lire le Guide de Beej sur la programmation réseau . Peut-être qu’un livre pourrait même être utile …

  1. Non, la fonction read () effectue la lecture, pas le serveur. Sur cette note, il serait judicieux de stocker la valeur de retour de read () quelque part et de déterminer ce qui est significatif à ce sujet. Voici le manuel, si vous croyez, comme beaucoup d’entre nous, que la lecture est un mécanisme plus efficace que les essais et les erreurs.
  2. Non. U_open semble renvoyer un socket serveur, dont read () n’est pas une action valide, bien qu’accepter () l’est. u_accept semble retourner un socket pair, dont accept () n’est pas une action valide, bien que read () soit.
  3. Bien sûr, à condition que le port soit supérieur à 1024 (moins de 1024 nécessite généralement des privilèges de superutilisateur), inférieur à 65535 et que le port n’est pas déjà lié.