2012-02-18 75 views
0

我可以撥打receive {tcp, Socket, Bin} ->電話嗎?例如,我有一個名爲Loop的頂級循環,它在接收到tcp數據時會調用一個函數parse_header來解析頭數據(一個整數,指示要遵循的數據類型以及它的大小),然後我需要接收整個有效載荷繼續前進。

當我需要一個完整的20字節並且想要在一個名爲parse_payload的單獨函數中調用receive時,我可能只會收到4個字節。因此,呼叫鏈看起來像loop->parse_header->parse_payload,我希望parse_payload致電
receive {tcp, Socket, Bin} ->

我不知道這是否可以,或者我是否完全搞砸了,只能在Loop函數中做到。有人能夠啓發我嗎?如果我被允許這樣做,我是否違反了某種最佳做法?應該/我可以爲TCP數據做嵌套接收嗎?

回答

2

也許你可以檢查「erlang編程」的示例代碼。 下載頁面爲Erlang Programming Source Code

在文件socket_examples.erl中,請檢查「receive_data」函數。對於perse消息,我認爲你應該確定如何逐個分離消息(固定長度或終止字節),然後解析消息的頭部和有效負載。

 
receive_data(Socket, SoFar) -> 
    receive 
    {tcp,Socket,Bin} -> %% (3) 
     receive_data(Socket, [Bin|SoFar]); 
    {tcp_closed,Socket} -> %% (4) 
     list_to_binary(reverse(SoFar)) %% (5) 
    end. 
1

您還可以在被動模式下設置gen_tcp套接字。這樣,擁有進程將不會收到消息的輸入,但必須使用gen_tcp:recv(Socket,ByteCount)獲取它,它返回{ok,Input}{error,Reason}。由於此方法無限期地等待使用gen_tcp:recv/3可能需要添加超時的字節。 (Erlang documentation of gen_tcp:recv

雖然乍看之下,似乎這個過程現在已經完全無法對發送給它的信息作出反應,有以下解決方法改善這種情況有點:

f1(X) -> 
    receive 
     message1 -> 
      ... do something ..., 
      f1(X); 
     message2 -> 
      ... do something ..., 
      f1(X) 
     after 0 %timeout in ms 
      {ok, Input} = gen_tcp:recv(Socket, ByteCount, Timeout), 
      ... do something ... % maybe call some times gen_tcp:recv again 
      f1(X) 
    end. 

如果你不」 t在這裏爲gen_tcp:recv添加一個超時,其他進程可能會等待f1處理它們的消息。

相關問題