2010-11-02 21 views
2

J'ai un serveur client de base en erlang qui utilise tcp.envoi binaire brut en utilisant tcp dans erlang

Comment envoyer les données binaires réelles d'un fichier au client qui l'a demandé?

Comment le fichier est-il envoyé en pièces?

J'ai ce code

{ok, Socket} = gen_tcp:connect({Ip}, 2345, [binary, {packet, 4}]),

Est-ce que ce paquet {4} gérer la taille des données qui est d'envoyer les deux sens?

De même, comment le client reçoit-il des données et ensuite fait quelque chose avec lui? Comme l'enregistrer dans un fichier?

Merci

+2

Il y a beaucoup de questions ici. Vous feriez peut-être mieux de le diviser en petites questions. Vous pourriez également bénéficier de cela: http://20bits.com/articles/erlang-a-generalized-tcp-server/ – nmichaels

Répondre

8

Oui - {packet, 4} causeront Erlang d'exiger une trame de paquet d'une valeur grande longueur entière endian non signé de 4 octets en réception, et émettra un avant chaque paquet de données envoyées.

Vous pouvez envoyer des données sur le socket en appelant le gen_tcp:send(Socket, Data). Cela fera quelque chose comme:

RawData = iolist_to_binary(Data), 
Length = byte_size(RawData), 
Packet = <<Length:32/big-unsigned-integer, RawData/binary>>, 
send(Socket, Packet). 

donc à condition que votre fichier est inférieure à 4Gb, vous pouvez l'envoyer en faisant

{ok, File} = file:read_file(FileName), 
gen_tcp:send(Socket, File). 

Sur la réception:

File = gen_tcp:recv(Socket, 0). 

Vous aurez obtenir le fichier complet en raison du cadrage {packet, 4}.

+0

Merci. Si les données entrantes font partie d'un fichier, sans ordre spécifique (BITFIELD de torrent) et que j'écris dans un fichier après un certain buffer ou des morceaux reçus, comment cela affectera-t-il le {paquet, someValue}? Aussi avec File = gen_tcp: recv (Socket, 0) ce fichier sera-t-il stocké en mémoire et pourra-t-il être écrit sur le disque lorsque le fichier entier sera reçu? – jarryd

+0

'Packet, 4' vous donne seulement un cadrage. Bittorrent est son propre protocole que vous devez implémenter séparément (et parce que bittorrent spécifie quelque chose d'autre que le framing de {{packet, 4}), vous finirez par utiliser '{packet, raw}'). Vous pouvez regarder une implémentation d'erlang pour des exemples de comment faire ceci - essayez http://github.com/jlouis/etorrent/tree/ – archaelus