2010-09-07 5 views
3

J'ai un serveur des thats envoyer des enregistrements de données sous forme de chaînes de longueur variable (par exemple, 79,80,81,82)synchronisation entre send/recv dans les prises

Je veux être en mesure de recevoir exactement un enregistrement à la fois.J'ai délimité des enregistrements avec un (r) mais parce que je ne sais pas combien d'octets je dois recevoir, il fusionne parfois des dossiers et il est difficile pour moi de traiter.

Répondre

4

J'ai deux idées pour vous:

  1. Utilisez XML pour le protocole. De cette façon, vous savez exactement quand chaque message se termine.
  2. Envoyer dans l'en-tête de chaque "paquet" la taille du paquet, de cette façon, vous savez combien de lire à partir du socket pour ce paquet spécifique.

Edit: Regardez ce code factice pour (2)

int buffer_size; 
char* buffer; 

read(socket, &buffer_size, sizeof(buffer_size)); 
buffer = (char*) malloc(packet_size); 
read(socket, buffer, buffer_size); 
// do something 
free(buffer) ; 

EDIT: Je recommande de regarder les commentaires ici, comme ils notent que le contect pourrait ne pas être prêt par un simple " read() ", vous devez garder" read() "ing, jusqu'à ce que vous obteniez la taille de tampon correcte.

Aussi - vous pourriez ne pas avoir besoin de lire la taille. Fondamentalement, vous devez rechercher la balise de fin de niveau supérieur du XML. Cela peut être fait en analysant l'ensemble du XML, ou en analysant le code XML que vous obtenez du flux jusqu'à ce que vous ayez 0 noeud "ouvert".

+0

ne peux pas faire cela sans xml? Je peux juste analyser l'en-tête moi-même? – aks

+0

Je pense que cela fonctionnera. Merci – aks

+1

Il n'y a aucune garantie que 'read()' lira exactement ce que vous demandez. Vous devez faire une boucle jusqu'à ce que vous obteniez la taille de paquet complète, et si vous faites cela, vous pourriez aussi bien faire une boucle en cherchant le délimiteur de fin de paquet. – caf

0

Envoyez-vous vos données sous forme de flux?

Vous pouvez l'envoyer sous la forme d'une structure dont il est plus facile d'analyser et d'extraire les données.

struct Message 
{ 
    int dataSize; 
    char data[256]; 
}; 
+0

no..It doit être un cours d'eau en raison de certaines autres contraintes – aks

+0

S'il vous plaît inverser la struct - dans la pratique, le DataSize sera envoyé en premier. Je sais que cela ne change pas comment cela fonctionne, mais sémantiquement c'est plus clair. – elcuco

+0

@elcuco - Merci pour le conseil. Édité en conséquence :) – bdhar

0

Vous devez délimiter avec un octet nul. Montrez-nous votre code, et nous pouvons être en mesure de vous aider.

+0

sauf si .... vous voulez envoyer ascii (0) .... – elcuco

+0

C'est le caractère le moins utilisé, car de nombreuses applications l'utilisent pour séparer ou terminer des segments de données. –

0

Les sockets de flux ne supportent pas nativement l'idée d'un «enregistrement» - l'abstraction qu'ils fournissent est celle d'un flux continu.

Vous devez implémenter une couche au-dessus d'eux pour fournir des "enregistrements". On dirait que vous êtes déjà à mi-chemin, avec le délimiteur de fin d'enregistrement. Le pseudo-code pour le compléter est:

create empty buffer; 
forever { 
    recv data and append to buffer; 

    while (buffer contains end-of-record marker) { 
     remove first record from buffer and process it; 
     move remaining data to beginning of buffer; 
    } 
} 
Questions connexes