sockets unix: comment envoyer vraiment gros volumes de données avec un « envoyer » appel?

StackOverflow https://stackoverflow.com/questions/1577825

  •  21-09-2019
  •  | 
  •  

Question

J'utilise scoket unix pour transfert de données (mode SOCK_STREAM)

Je dois envoyer une chaîne de plus de 100k caractères. Tout d'abord, je vous envoie la longueur d'une chaîne - c'est sizeof (int) octets.

length = strlen(s)
send(sd, length, sizeof(int))

Puis-je envoyer toute la chaîne

bytesSend = send(sd, s, length)

mais pour ma grande surprise "bytesSend" est inférieur à "longueur".

Notez que cela fonctionne très bien quand j'envoie pas si grandes chaînes. Peut-être il existe certaines limites pour l'appel système « envoyer » que j'ai manque ...

Était-ce utile?

La solution

L'appel système send est censé être rapide , parce que le programme peut avoir d'autres choses à faire des choses utiles. Certes, vous ne voulez pas attendre que les données soient envoyées et l'autre ordinateur pour envoyer une réponse -. Qui conduirait à un débit affreux

Alors, tout send fait vraiment est en file d'attente des données pour l'envoi et renvoie le contrôle au programme. Le noyau peut copier l'intégralité du message dans la mémoire du noyau, mais cela consomme beaucoup de mémoire du noyau (pas bon).

Au lieu de cela, le noyau des files d'attente seulement comme une grande partie du message comme raisonnable. Il est de la responsabilité du programme de re-tentative d'envoyer des données restantes.

Dans votre cas, utilisez une boucle pour envoyer les données qui ne sont pas envoyés la première fois.

while(length > 0) {
    bytesSent = send(sd, s, length);
    if (bytesSent == 0)
        break; //socket probably closed
    else if (bytesSent < 0)
        break; //handle errors appropriately
    s += bytesSent;
    length -= bytesSent;
}

A la fin de réception, vous aurez probablement besoin de faire la même chose.

Autres conseils

Votre premier appel send() est erroné. Vous devez passer send () l'adresse des données, i.e.:.

bytesSend = send(sd, &length, sizeof(int))

En outre, cela se heurte à certains risques classiques, avec boutisme, la taille de int sur différentes plates-formes, et ainsi de suite.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top