[Erlang 0075] Bad value on output port 'tcp_inet'



  小超同學遇到一個問題:gen_tcp:send方法報錯, Bad value on output port 'tcp_inet';按照字面意思是發往port的數據值是bad value;
 
打開erl5.9\lib\kernel-2.15\src\gen_tcp.erl看一下gen_tcp的源碼:
 
%%
%% Send
%%

-spec send(Socket, Packet) -> ok | {error, Reason} when
      Socket :: socket(),
      Packet :: iodata(),    %%% <- 注意這里
      Reason :: inet:posix().

send(S, Packet) when is_port(S) ->
    case inet_db:lookup_socket(S) of
     {ok, Mod} ->
         Mod:send(S, Packet);
     Error ->
         Error
    end.

 

 從函數接口說明可以看出數據要求是iodata,估計出現'bad value'很有可能數據不是iodata,做個實驗看看:

Eshell V5.9  (abort with ^G)
1>  {ok,S0}=gen_tcp:listen(5678,[]).
{ok,#Port<0.506>}
2> {ok,S1}=gen_tcp:connect("localhost",5678,[]).
{ok,#Port<0.517>}
3> {ok,S2}=gen_tcp:accept(S0).
{ok,#Port<0.518>}
4> gen_tcp:send(S1,"message text\0").
ok
5> gen_tcp:send(S1,["message text",0]).
ok
6> gen_tcp:send(S1,["message text我們",0]).
ok
7> flush().
Shell got {tcp,#Port<0.518>,[109,101,115,115,97,103,101,32,116,101,120,116,0]}
Shell got {tcp,#Port<0.518>,[109,101,115,115,97,103,101,32,116,101,120,116,0]}
Shell got {tcp,#Port<0.518>,
               [109,101,115,115,97,103,101,32,116,101,120,116,206,210,195,199,
                0]}
ok
8> gen_tcp:send(S1,["message text我們",msg,0]).
{error,einval}

=ERROR REPORT==== 23-Aug-2012::11:37:23 ===
Bad value on output port 'tcp_inet'

9> gen_tcp:send(S1,["message text我們",0]).
ok
10> gen_tcp:send(S1,["message text我們",12,0]).
ok
11> gen_tcp:send(S1,["message text我們",1222,0]).
{error,einval}

=ERROR REPORT==== 23-Aug-2012::11:57:24 ===
Bad value on output port 'tcp_inet'

12>

 

重現了小超遇到的問題,,只要發送的數據不是iodata就會報Bad value on output port 'tcp_inet'的錯誤,根據這個線索,小超同學跟了一下果然由於協議層代碼問題導致發送的數據是error_protocol這樣一個原子.

 

關於iodata和iolist這個我之前整理過一篇文章[鏈接],這里只把iodata的定義再貼一遍:

iodata() = iolist() | binary()
iolist() maybe_improper_list(char() | binary() | iolist(), binary() | [])
maybe_improper_list() maybe_improper_list(any(), any())
byte() 0..255
char() 0..16#10ffffmaybe_improper_list(T) maybe_improper_list(T, any())

或者:

IoData = unicode:chardata()
chardata() = charlist() | unicode_binary()
charlist() = [unicode_char() | unicode_binary() | charlist()]
unicode_binary() = binary()

A binary() with characters encoded in the UTF-8 coding standard.

  

 下面資料遇到的情況是同樣的原因:

 [1] http://www.trapexit.org/forum/viewtopic.php?p=39602&sid=ba065c1a5b0c789b4383501784d416ec

 [2] http://erlang.org/pipermail/erlang-questions/2009-September/046396.html

 

小圖一張

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM