2010-11-02 70 views
2

我在使用tcp的erlang中有一个基本的客户端服务器。在erlang中使用tcp发送原始二进制文件

如何将文件中的实际二进制数据发送给请求它的客户端?

文件是如何发送的?

我有这样的代码

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

这是否{包,4}处理的数据大小是发送两种方式?

此外,客户端如何接收数据,然后做些什么呢?像保存到一个文件?

由于

+2

这里有很多问题。将它分解成更小的问题可能会更好。您也可能从中受益:http://20bits.com/articles/erlang-a-generalized-tcp-server/ – nmichaels 2010-11-02 19:52:02

回答

8

是 - {packet, 4}将导致二郎要求4字节的无符号大端整数长度上接收值的分组帧,并且将发出一个发送的数据的每个分组之前。

您可以通过调用gen_tcp:send(Socket, Data)在套接字上发送数据。这会做这样的事情:

File = gen_tcp:recv(Socket, 0). 

你会:

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

所以,只要你的文件小于4GB,你可以通过做

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

在接收端发送由于{packet, 4}成帧,请获取完整的文件。

+0

谢谢。如果传入数据是文件的一部分,没有特定的顺序(torrent的BITFIELD),并且在收到特定缓冲区或块后写入文件,这将如何影响{packet,someValue}?还有File = gen_tcp:recv(套接字,0)将这个文件存储在内存中,然后可以在收到整个文件时写入磁盘? – jarryd 2010-11-02 20:32:21

+0

'数据包,4'只给你取景。 Bittorrent是它自己的协议,你需要单独实现(并且由于bittorrent指定了除'{packet,4}'外的其他内容,所以最终会使用'{packet,raw}')。你可以看看一个erlang实现的例子,如何做到这一点 - 尝试http://github.com/jlouis/etorrent/tree/ – archaelus 2010-11-02 23:09:23