上下文:JA 的“Programming Erlang”2ed,第 16 章文件,第 256 页,使用从二进制文件解析 url 的示例。
建议的步骤(在为 scavenge_urls 模块编写代码之后)如下:
B = socket_examples:nano_get_url("www.erlang.org"),
L = scavenge_urls:bin2urls(B),
scavenge_urls:urls2htmlFile(L,"gathered.html").
这(巧妙地)失败了 - 列表 L 最终为空。自行运行第一步,观察到一个奇怪的事情 - 它确实返回一个二进制文件,但它不是我正在寻找的二进制文件:
9> B.
<<"HTTP/1.1 404 Not Found\r\nServer: nginx\r\nDate: Sun, 19 Nov 2017 01:57:07 GMT\r\nContent-Type: text/html; charset=UTF-8\r\n"...>>
shows that this is where the problem lies.
但在浏览器中,母舰一切正常!我能够通过替换对 socket_examples:nano_get_urls/1 的调用来完成练习,首先,对相同的 url 进行 CURL,将其转储到文件中,然后是 file:read_file/1。接下来的步骤都运行良好。
偷看 socket_examples 模块,我看到了这个:
nano_get_url(Host) ->
{ok,Socket} = gen_tcp:connect(Host,80,[binary, {packet, 0}]), %% (1)
ok = gen_tcp:send(Socket, "GET / HTTP/1.0\r\n\r\n"), %% (2)
receive_data(Socket, []).
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.
看起来没什么可疑的。首先它建立连接,然后触发 GET,然后接收响应。我以前从来没有必须先显式连接,然后再触发 GET,我的 http 客户端库对我隐藏了这一点。所以也许我不知道要寻找什么……而且我确信乔的代码没有任何明显的错误!=) 然而,带有注释 (3)、(4) 和 (5) 的行并不是我完全理解的。
那么,有什么想法吗,厄兰格兄弟们?谢谢一堆!