how to perform non-blocking net.listen_tcp

Discuss your Lua playlist, album art and interface scripts.
khuankhuan
Blank Cone
Blank Cone
Posts: 13
Joined: 02 Nov 2011 17:34

how to perform non-blocking net.listen_tcp

Postby khuankhuan » 13 Mar 2012 16:05

How can I perform a non-blockin net.listen_tcp in lua?

Currently from the readme I am using the following script:

Code: Select all

local l = vlc.net.listen_tcp( "localhost", 1234 ) while true do local fd = l:accept() if fd >= 0 do net.send( fd, "blabla" ) net.close( fd ) end end
The readme said that: Poll on the fds with the net.POLLIN flag if you want to be non blocking. The fds method returns a list of fds you can call poll on before using the accept method.

Which part of the code I should modify to make it become a non blocking listen? Please help here thanks!

exebetche
Blank Cone
Blank Cone
Posts: 12
Joined: 04 Mar 2012 05:32

Re: how to perform non-blocking net.listen_tcp

Postby exebetche » 13 Mar 2012 20:30

This is an working example of "net.poll" that I wrote for Vlsub. It just perform a get, using "vlc.net.send(fd, request)" to send request and vlc.net.POLLIN + "vlc.net.recv(fd, 1024)" to get data from the server.
If it doesn't suit you, you need to be more specific.

Code: Select all

function test() get("http://www.videolan.org/developers/vlc/share/lua/README.txt") end function get(url) local host, path = parse_url(url) local header = { "GET "..path.." HTTP/1.1", "Host: "..host, "User-Agent: "..userAgentHTTP, "", "" } local request = table.concat(header, "\r\n") local response local status, response = http_req(host, 80, request) if status == 200 then return response else return false end end function http_req(host, port, request) local fd = vlc.net.connect_tcp(host, port) if fd >= 0 then local pollfds = {} pollfds[fd] = vlc.net.POLLIN vlc.net.send(fd, request) vlc.net.poll(pollfds) local response = vlc.net.recv(fd, 1024) local headerStr, body = string.match(response, "(.-\r?\n)\r?\n(.*)") local header = parse_header(headerStr) local contentLength = tonumber(header["Content-Length"]) local TransferEncoding = header["Transfer-Encoding"] local status = tonumber(header["statuscode"]) local bodyLenght = string.len(body) local pct = 0 if status ~= 200 then return status end while contentLength and bodyLenght < contentLength do vlc.net.poll(pollfds) response = vlc.net.recv(fd, 1024) if response then body = body..response else vlc.net.close(fd) return false end bodyLenght = string.len(body) pct = bodyLenght / contentLength * 100 --setMessage(openSub.actionLabel..": "..progressBarContent(pct)) end vlc.net.close(fd) return status, body end return "" end function parse_header(data) local header = {} for name, s, val in string.gfind(data, "([^%s:]+)(:?)%s([^\n]+)\r?\n") do if s == "" then header['statuscode'] = tonumber(string.sub (val, 1 , 3)) else header[name] = val end end return header end

khuankhuan
Blank Cone
Blank Cone
Posts: 13
Joined: 02 Nov 2011 17:34

Re: how to perform non-blocking net.listen_tcp

Postby khuankhuan » 17 Mar 2012 07:59

Thanks for the reply, but its not what I am looking for. I am looking for a non-blocking vlc.net.listen_tcp method, there are 2 methods available, which are accept and fds, as shown in the code in my first post. But the problem is that the accept method is blocking, meaning the lua will stop at the accept line until it receives a connection.

I am implementing a server and a client, the server is using the net.listen_tcp while the client uses the net.connect_tcp, I had implemented your poll method in the client but for the server side I have no idea how to use the fds method, please help thanks.

exebetche
Blank Cone
Blank Cone
Posts: 12
Joined: 04 Mar 2012 05:32

Re: how to perform non-blocking net.listen_tcp

Postby exebetche » 18 Mar 2012 21:12

Did you try to replace vlc.net.listen_tcp by vlc.net.connect_tcp with the poll method?
Or maybe the telnet or rc interface will do the trick.

khuankhuan
Blank Cone
Blank Cone
Posts: 13
Joined: 02 Nov 2011 17:34

Re: how to perform non-blocking net.listen_tcp

Postby khuankhuan » 20 Mar 2012 15:15

Did you try to replace vlc.net.listen_tcp by vlc.net.connect_tcp with the poll method?
Or maybe the telnet or rc interface will do the trick.
Nope, it doesn't solve the problem, it has to do with the method returned by the vlc.net.listen_tcp. Guess all developers are just too busy...

Vhati
Blank Cone
Blank Cone
Posts: 16
Joined: 06 Apr 2011 08:07

Re: how to perform non-blocking net.listen_tcp

Postby Vhati » 22 May 2012 18:04

In the VLC source code (/modules/lua/libs/net.c), the lua vlc.net.poll({fds}) func maps to this.

Code: Select all

i_ret = poll( p_fds, i_fds, -1 );
int poll(struct pollfd *fds, nfds_t nfds, int timeout);
The timeout argument specifies an upper limit on the time for which poll() will block, in milliseconds. Specifying a negative value in timeout means an infinite timeout.
So calling poll() in scripts will introduce indefinite blocking because of that hardcoded -1.

Aside: this bit me yesterday.* Turned out vlc.net.recv() is non-blocking, returning nil instead of a string if the socket wasn't ready to be read from. So when writing a client, after connecting it's important to poll() for vlc.net.POLLIN which causes the script to wait for a server response to arrive before attempting recv. On the other hand, to make a non-blocking client, one could just recv at will and handle nils.
* I made a test server that slept for a couple seconds before telling clients "hello world" and had VLC print debug messages to confirm poll was blocking for that duration and then letting recv kick in.

For a non-blocking server... I haven't tried this, but if accept() blocks, and poll({fds}) blocks until something's ready to act on, you could include in your fds a dummy source that's always ready to read. Poll should immediately return. Then if a non-dummy also happens to also be ready for accepting, you can handle that. Possible pitfall: If the brief poll doesn't sleep at all, it might not like being in a while loop unless you add a sleep of your own... or put the polling in a periodically-triggered event instead.

dhruvbird
New Cone
New Cone
Posts: 2
Joined: 03 May 2013 09:12

Re: how to perform non-blocking net.listen_tcp

Postby dhruvbird » 03 May 2013 09:21

> or put the polling in a periodically-triggered event instead.

What is this "periodically-triggered event" that you speak of? Is there a timer interrupt available to hook on to?


Return to “Scripting VLC in lua”

Who is online

Users browsing this forum: No registered users and 7 guests