2010-08-28 22 views
0

Je télécharge 6kB de données à partir d'un instrument de test connecté via socket TCP. J'utilise SOCK_STREAM:Je dois être en train de courir dans une limite de tampon quelque part recevoir des données du socket TCP en utilisant recv()

if((MySocket=socket(PF_INET,SOCK_STREAM,0))==-1) exit(1); 

Je n'ai pas mis les I toutes les tailles de tampon, donc suppose que je suis sur ce que la valeur par défaut est. J'ai un problème avec la réception de données. Voici l'instruction:

if((recv(MySocket, &YRaw[indx], sizeChunk*2, 0))==-1) 
    {perror("recv()"); exit(9); } // where sizeChunk=3000; sizeof(YRaw[0])=2 

où YRaw est un tableau d'objets 3000, chaque objet est de 2 octets. Le problème que j'observe après l'exécution du code, est celui d'environ les 3/4 de YRaw, il y a une chaîne de zéros, qui sont ce que j'ai initialisé le tableau. Il semble que la fonction de réception fonctionne bien jusqu'aux 3/4 de la matrice, puis saute un segment de la matrice YRaw (en laissant les valeurs initialisées), puis reprend à nouveau et la matrice YRaw se remplit. Il reste des données à lire dans le tampon, égal au nombre de valeurs ignorées dans le tableau YRaw. Je soupçonne que cela est lié à un peu de tampon dans le système. Quelqu'un peut-il faire la lumière sur la façon de résoudre ce problème?

Je ne sais pas si elle est liée, mais j'ai aussi mis TCP_NODELAY, ici:

// TCP_NODELAY option minimizes latency by instructing system to send small msgs immediately 
// Insert setsockopt() before connect() occurs 
int StateNODELAY = 1; // turn NODELAY on 
if(setsockopt(MySocket, IPPROTO_TCP,TCP_NODELAY, 
    (void *) &StateNODELAY, sizeof StateNODELAY)==-1) {perror("setsockopt()"); exit(2); }; 

Meilleures salutations, GKK

Répondre

3

recv() ne remplit pas nécessairement le tampon entier. Il lit juste ce qui est disponible et retourne combien d'octets ont été lus. Donc inspectez la valeur de retour pour voir combien de données étaient disponibles, traitez ces données et appelez recv() jusqu'à ce que vous ayez reçu toutes les données que vous attendez.

+1

Vous pouvez également utiliser l'indicateur WAITALL pour bloquer jusqu'à ce que toutes les données demandées aient été lues ou qu'une erreur se soit produite. –

+0

Pourriez-vous décrire comment utiliser WAITALL. Cela semble prometteur ... quel fichier #include <___.h> ai-je besoin? A quoi ressemble un exemple de ligne de code? – ggkmath

+1

Sous Linux, MSG_WAITALL est un indicateur optionnel, donné en tant que 4ème argument (c'est-à-dire au lieu du 0 dans votre appel recv) –

0

Vous devez stocker définitivement le résultat de recv (c'est-à-dire non seulement de vérifier s'il s'agit de -1 ou non). C'est la taille des octets réellement lus et vous avez besoin de cela pour savoir combien d'octets sont valides dans votre tampon. En dehors de cela, vous devriez vérifier si vous pouvez lire plus d'octets sans bloquer et lire plus jusqu'à ce que cela bloque.

Les limitations de taille de tampon peuvent être n'importe où dans le système, par ex. le MTU Ethernet ou même sur votre appareil émetteur.

+0

THanks, OK J'ai modifié le programme, et je peux voir que, comme indiqué ci-dessus, il lit 4342 octets sur les 6000 octets demandés. t envoyé plus de 4342 octets avant la fonction recv terminée? Je ne suis pas sûr de ce que vous entendez par "bloquer ou" bloquer "ici J'utilise un programme similaire dans Matlab et ça fonctionne bien (mêmes machines/ – ggkmath

+0

En outre, si je casse la lecture en 5 lectures de 1200 octets chacune, les 3 premiers recv retournent les 1200 octets attendus, le quatrième recv lit 742 octets, et t Le dernier recv lit 1200 octets. Est-ce que cela aide à expliquer comment le réparer? – ggkmath

+0

Hmm, pourquoi le quatrième recv() retournerait moins que les 1200 octets attendus, si le cinquième recv() renvoie le 1200B complet? Ne serait pas le quatrième recv() attendre le ... Aaahaa !!! De ce que sth dit ci-dessus, la commande recv() ne remplit pas nécessairement tout le tampon. Ainsi, l'instrument de test diffuse probablement les données et la quatrième lecture lit simplement tout ce qui est disponible puis renvoyé. Au moment où le cinquième recv() est arrivé, il y avait plus de données disponibles à lire. Ça a du sens, mais je suppose que WAITALL est la réponse (?). – ggkmath