2010-04-17 10 views
1

J'ai un serveur et un client fonctionnant sur deux machines différentes où le client send() s mais le serveur ne semble pas recevoir le message. Le serveur utilise select() pour surveiller les sockets pour les connexions/messages entrants. Je peux voir que lorsque le serveur accepte une nouvelle connexion, il met à jour le tableau fd_set mais renvoie toujours 0 malgré les messages send() du client. La connexion est TCP et les machines sont séparées par un routeur de sorte que les paquets qui tombent sont hautement improbables.Programmation socket S: client send() mais serveur select() ne le voit pas

J'ai le sentiment que ce n'est pas select() mais peut-être send()/sendto() du client qui peut être le problème, mais je ne suis pas sûr de savoir comment s'y prendre localisant la zone de problème.

while(1) 
{ 
    readset = info->read_set; 
    ready = select(info->max_fd+1, &readset, NULL, NULL, &timeout); 

}

ci-dessus est le code côté serveur où le serveur a un fil qui fonctionne select() indéfiniment.

rv = connect(sockfd, (struct sockaddr *) &server_address, sizeof(server_address)); 
printf("rv = %i\n", rv); 
if (rv < 0) 
{ 
    printf("MAIN: ERROR connect() %i: %s\n", errno, strerror(errno)); 
    exit(1); 
} 
else 
    printf("connected\n"); 

sleep(3); 

char * somemsg = "is this working yet?\0"; 
rv = send(sockfd, somemsg, sizeof(somemsg), NULL); 
if (rv < 0) 
    printf("MAIN: ERROR send() %i: %s\n", errno, strerror(errno)); 
printf("MAIN: rv is %i\n", rv); 
rv = sendto(sockfd, somemsg, sizeof(somemsg), NULL, &server_address, sizeof(server_address)); 
if (rv < 0) 
    printf("MAIN: ERROR sendto() %i: %s\n", errno, strerror(errno)); 
printf("MAIN: rv is %i\n", rv); 

ce qui est du côté client où il se connecte et envoie des messages et retourne

connected 
MAIN: rv is 4 
MAIN: rv is 4 
+1

Quel est le contenu de 'info-> read_set'? A-t-il été correctement initialisé en utilisant 'FD_SET'? – qrdl

+0

J'ai initialisé en utilisant FD_SET mais maintenant que vous le mentionnez, j'ai bricolé avec FD_SET et j'ai constaté que je faisais quelque chose de mal. Je vous créditerais si je le pouvais :) –

+0

'sizeof (somemsg)' est 4 parce que 'somemsg' a le type' char * ', et les pointeurs ont une taille de 4 octets sur votre système. Donc, vous n'envoyez que les 4 premiers octets de 'somemsg'. Vous devriez déclarer 'somemsg' être de type' char [] ', pas' char * '. –

Répondre

0

connecté
PRINCIPAL: autocaravane 4
MAIN: rv est 4

Odd que "RV est 4", d'autant plus que le message était de 22 caractères. "4" a également tendance à être la taille des pointeurs dans la plupart des environnements 32 bits. Vous devriez jeter un coup d'oeil à ce que sizeof(somemsg) vous donne; je suppose que c'est vous donner la taille du pointeur (4), pas de la corde (22).

Où mettez-vous à jour le jeu de lecture? Les détails d'implémentation de la structure/type fd_set ne font pas partie de l'interface des sockets BSD, pour autant que je sache. Cela pourrait être un pointeur vers quelque part, pour autant que vous sachiez, et le système pourrait supprimer le socket de votre client de l'ensemble original la première fois qu'il n'était pas "prêt", et ne plus jamais le vérifier. La seule façon de mettre à jour un fd_set en toute sécurité et de manière portable consiste à utiliser les macros FD_*. Par ailleurs, vous n'avez pas besoin de la fin \0 à la fin de la chaîne. C ajoute cela aux chaînes littérales pour vous.

+0

Merci pour le conseil, je n'étais pas trop sûr. Et oui, j'ai utilisé les macros FD_ * pour mettre à jour 'fd_set's. Il s'avère que je ne m'étais pas initialisé correctement lorsque je l'ai installé à partir du bloc de mémoire que le thread partage. –

+0

Ce que je veux dire, c'est "this_fd_set = another_fd_set;" est potentiellement dangereux. Si la plate-forme sur laquelle vous travaillez implémente fd_set en utilisant des pointeurs pour une raison quelconque (ce qui est autorisé!), certaines (éventuellement) toutes les données seront partagées entre les deux ensembles. Et mettre à jour un pourrait gâcher l'autre. – cHao

0

Quelque chose n'allait pas avec fd_set readset, plutôt que ce que je pensais être problématique. PROPS à qrdl pour l'avoir porté à mon attention.