microwish
Hi Yichun,
The receive function returned an error saying "closed".
Sample codes follow:
<code>
local sockfd, err = ngx.socket.tcp()
if not socked then return nil, err end
sockfd:settimeout(BIG_ENOUGH_VALUE)
local r
r, err = sockfd:connect(HOST, PORT)
if not r then return nil, err end
--r, err = sockfd:send(SOME_DATA)
r, err = sockfd:send("hello world")
if not r then sockfd:close(); return nil, err end
local part
r, err, part = sockfd:receive(8)
--for debug
print("part type: ", part, ". part len: ", #part)
if not r then
--for debug
print("receive failed: ", err)
sockfd:close()
return nil, err
end
sockfd:close()
--......
</code>
The receive function returned an error saying "closed", while functions of connect and send working well.
Skipping through functions of ngx_http_lua_socket_tcp_receive, ngx_http_lua_socket_tcp_retval_handler, ngx_http_lua_socket_push_input_data and ngx_http_lua_socket_error_retval_handler in ngx_http_lua_socket_tcp.c, I knew the error was generated in the following snippets, i.e. lines from 1810 to 1832:
<code>
if (u->ft_type) {
dd("u->bufs_in: %p", u->bufs_in);
if (u->bufs_in) {
rc = ngx_http_lua_socket_push_input_data(r, ctx, u, L);
if (rc == NGX_ERROR) {
lua_pushnil(L);
lua_pushliteral(L, "out of memory");
return 2;
}
(void) ngx_http_lua_socket_error_retval_handler(r, u, L);
lua_pushvalue(L, -3);
lua_remove(L, -4);
return 3;
}
n = ngx_http_lua_socket_error_retval_handler(r, u, L);
lua_pushliteral(L, "");
return n + 1;
}
</code>
but I failed to probe further.
Could you give any suggestions?
Thank you very much.
agentzh
Hello!
On Wed, Aug 7, 2013 at 11:07 PM, microwish wrote:
> The receive function returned an error saying "closed".
>
[...]
>
> r, err, part = sockfd:receive(8)
When receive(N) returns the error "closed", it usually means that the
remote end does not send enough data before closing the connection.
Unlike the BSD-style socket API's recv(), cosocket's receive()
requires receiving exactly the same number of data (or more data),
which is identical LuaSocket's behavior. Please see the official
documentation for the receive() method for more details:
http://wiki.nginx.org/HttpLuaModule#tcpsock:receive
You can use the receive("*a") in your Lua code instead to check what
data your backend actually returns. Alternatively you can just use
tools like tcpdump to inspect the packets.
Best regards,
-agentzh