Threading+TCPServer issues on Win32

B

Bill Atkins

I'm having an issue with threading and TCP servers on Win32. I've
boiled down the issue to the following code:

-----

require 'socket'

t =3D Thread.new do
serv =3D TCPServer.new '', 344
sock =3D serv.accept
sock.puts "ok"
sock.close
serv.close
end

puts "OK, enter text: "
puts gets

-----

So with a server listening in the background, the program should
accept one new request and respond with "ok". In the meantime, it
should be waiting for the user to enter text on STDIN.

If this program is running in a UNIX environment, I can telnet to port
344 and I'll be greeted with "ok" and the program will continue to
wait for user input. However, when I run the same code on Windows,
the connection on port 344 opens (i.e. there is no connection refused
error), but no text is received. If I enter a word on the server's
STDIN and hit enter, the server quits and the connection is severed,
but the "ok" still doesn't get to the client.

I am quite possibly missing something obvious here, but I'm not sure
what it is. Any help would be appreciated.

--=20
Bill Atkins
 
S

Simon Kröger

Bill said:
I'm having an issue with threading and TCP servers on Win32. I've
boiled down the issue to the following code:

-----

require 'socket'

t = Thread.new do
serv = TCPServer.new '', 344
sock = serv.accept
sock.puts "ok"
sock.close
serv.close
end

puts "OK, enter text: "
puts gets

-----

So with a server listening in the background, the program should
accept one new request and respond with "ok". In the meantime, it
should be waiting for the user to enter text on STDIN.

If this program is running in a UNIX environment, I can telnet to port
344 and I'll be greeted with "ok" and the program will continue to
wait for user input. However, when I run the same code on Windows,
the connection on port 344 opens (i.e. there is no connection refused
error), but no text is received. If I enter a word on the server's
STDIN and hit enter, the server quits and the connection is severed,
but the "ok" still doesn't get to the client.

I am quite possibly missing something obvious here, but I'm not sure
what it is. Any help would be appreciated.

Hi Bill,

that's the same problem as

require 'timeout'
timeout(1){ puts gets }

this will never return (or throw the timeout exception) as
long as you do not hit a key.
Ruby has no native threads, it gets stuck on blocking system
calls.

I tried to circumvent the problem with Kernel#select, but for
some reason

select( [$stdin], nil, nil, 1.5 )

always returns immediately. Is there someone who can explain?

cheers

Simon
 
J

Joel VanderWerf

Simon Kr=F6ger wrote:
...
require 'timeout'
timeout(1){ puts gets }
=20
this will never return (or throw the timeout exception) as
long as you do not hit a key.
Ruby has no native threads, it gets stuck on blocking system
calls.

Is this only with a tty, and not a problem with sockets, files, etc.?

--=20
vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407
 
B

Bill Atkins

Right, I tried select as well, but no dice. Is there some workaround,
aside from splitting off separate processes?

Bill

Bill Atkins wrote:
=20
I'm having an issue with threading and TCP servers on Win32. I've
boiled down the issue to the following code:

-----

require 'socket'

t =3D Thread.new do
serv =3D TCPServer.new '', 344
sock =3D serv.accept
sock.puts "ok"
sock.close
serv.close
end

puts "OK, enter text: "
puts gets

-----

So with a server listening in the background, the program should
accept one new request and respond with "ok". In the meantime, it
should be waiting for the user to enter text on STDIN.

If this program is running in a UNIX environment, I can telnet to port
344 and I'll be greeted with "ok" and the program will continue to
wait for user input. However, when I run the same code on Windows,
the connection on port 344 opens (i.e. there is no connection refused
error), but no text is received. If I enter a word on the server's
STDIN and hit enter, the server quits and the connection is severed,
but the "ok" still doesn't get to the client.

I am quite possibly missing something obvious here, but I'm not sure
what it is. Any help would be appreciated.
=20
Hi Bill,
=20
that's the same problem as
=20
require 'timeout'
timeout(1){ puts gets }
=20
this will never return (or throw the timeout exception) as
long as you do not hit a key.
Ruby has no native threads, it gets stuck on blocking system
calls.
=20
I tried to circumvent the problem with Kernel#select, but for
some reason
=20
select( [$stdin], nil, nil, 1.5 )
=20
always returns immediately. Is there someone who can explain?
=20
cheers
=20
Simon
=20
=20


--=20
Bill Atkins
 
B

Bill Kelly

From: "Simon Kr=F6ger said:
that's the same problem as

require 'timeout'
timeout(1){ puts gets }

this will never return (or throw the timeout exception) as
long as you do not hit a key.
Ruby has no native threads, it gets stuck on blocking system
calls.

I tried to circumvent the problem with Kernel#select, but for
some reason

select( [$stdin], nil, nil, 1.5 )

always returns immediately. Is there someone who can explain?

Yes, unfortunately select() on windows only works with
sockets.

I don't know if this will be of any help, but I've used
the following workaround:

if WINDOWS_VERSION
require 'dl'
$win32_console_kbhit =3D Win32API.new("msvcrt", "_kbhit", [], 'I')
def console_input_ready?
$win32_console_kbhit.call !=3D 0
end
else
def console_input_ready?
select([$stdin], nil, nil, 0) !=3D nil
end
end


...it's not foolproof. If you do a gets() when
console_input_ready? is true on windows, you'll still block
until the user hits <enter>.


Regards,

Bill
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,787
Messages
2,569,631
Members
45,338
Latest member
41Pearline46

Latest Threads

Top