Communication socket client / serveur (AF_UNIX)

J’essaie d’écrire un programme client et un programme serveur dans lequel, lorsque le client se connecte au serveur, le serveur lui renvoie une chaîne aléatoire. Voici ce que j’ai jusqu’à présent (lecture du fichier omis):

serveur.c

#include  #include  #include  #include  #include  #include  #include  int listfd; int connfd; int main(int argc, char *argv[]){ /* * Create Sockets */ listfd = socket(AF_UNIX, SOCK_STREAM, 0); if(listfd == -1) exit(-1); struct sockaddr saddr = {AF_UNIX, "server"}; socklen_t saddrlen = sizeof(struct sockaddr) + 6; bind(listfd, &saddr, saddrlen); listen(listfd, 10); fflush(stdout); printf("Running...\n"); /* * Listen for connections * and send random phrase on accept */ while(1){ connfd = accept(listfd, NULL, NULL); int r = rand() % num_of_lines; //Pick random phrase/hint pair write(connfd, phrases[r], strlen(phrases[r])); close(connfd); sleep(1); } exit(0); } 

client.c

 #include  #include  #include  #include  #include  #include  #include  int main(int argc, char *argv[]) { int sock; int conn; struct sockaddr saddr = {AF_UNIX, "server"}; socklen_t saddrlen = sizeof(struct sockaddr) + 6; sock = socket(AF_UNIX, SOCK_STREAM, 0); conn = connect(sock, &saddr, saddrlen); char BUFF[1024]; read(sock, BUFF, 1024); printf("%s", BUFF); return 0; } 

Mon problème se pose lorsque j’essaie d’imprimer sur le client. J’exécute le serveur, mais lorsque j’exécute le client, il n’imprime que des caractères incohérents, et je ne suis pas tout à fait sûr de la cause.

Toute aide serait très appréciée, merci!

MODIFIER:

J’ai compris mon problème. Comme le socket du serveur était lié à “serveur”, qui était aussi le nom de l’exécutable, cela posait de nombreux problèmes.

Renommer le champ sockaddr.sa_data a résolu mon problème.

Vous avez un certain nombre de problèmes. C’est faux:

 struct sockaddr saddr = {AF_UNIX, "server"}; socklen_t saddrlen = sizeof(struct sockaddr) + 6; 

Vous dites au kernel “Voici un paquet d’octets représentant l’adresse du socket. C’est sizeof(struct sockaddr) + 6 octets”, mais vous ne passez que dans sizeof(struct sockaddr) . Résultat: le kernel lit votre adresse en dehors des limites, ce qui provoque au mieux l’échec de l’ EFAULT avec EFAULT et, au pire, le fait que le kernel lise des données EFAULT .

La méthode correcte pour configurer une adresse de socket AF_UNIX le type d’adresse de socket destiné aux sockets AF_UNIX , à savoir struct sockaddr_un (voir unix(7) ):

 struct sockaddr_un saddr = {AF_UNIX, "/socket/path"}; bind(listfd, (struct sockaddr *)&saddr, sizeof(saddr)); 

De même, le code client qui appelle connect(2) doit également configurer l’adresse de la même manière.

Ensuite, vous devez vérifier les erreurs. Presque tous les appels système ici peuvent échouer, vous devez donc rechercher les échecs après chaque appel et les gérer correctement (généralement, fermez le socket et / ou mettez fin au processus avec un message d’erreur approprié).

Comme vous l’avez mentionné, vous devez également choisir un nom de chemin approprié pour le socket. AF_UNIX sockets AF_UNIX nommés résident dans le système de fichiers et ne peuvent donc pas partager le même nom avec d’autres fichiers, y compris vos programmes serveur et client.

Votre appel à read(2) doit utiliser la valeur de retour pour déterminer le nombre d’octets lus. Il ne met PAS à zéro sa sortie – s’il lit 4 octets, ces 4 octets seront dans votre tampon et tout le rest sera indéterminé par la suite. Puisque printf s’attend à ce que son entrée soit à zéro terminal, vous devez soit explicitement le terminer lui-même, soit passer la longueur, par exemple:

 int n = read(sock, BUFF, sizeof(BUFF)); if (n < 0) { /* Handle error */ } printf("%.*s", n, BUFF); 
 read(sock, BUFF, 1024); 

NULL ne termine pas le tampon. Vous devez le faire explicitement. Il renvoie le nombre d’octets lus et copie les nombreux octets dans la mémoire tampon.

  readlen = read(sock, BUFF, 1024); BUFF[readlen] = '\0'; 

Vérifiez la valeur de retour de connect et read toute erreur éventuelle. Vérifiez ce que le serveur envoie.