2010-11-02 67 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