Can't get non-blocking TCP connect to work

H

Henrik Warne

Hello,

I am trying to do a non-blocking connect for a TCP connection, and I
can't get it to work.

I have googled a lot without finding a solution.

I do the following in ruby:


#!/usr/bin/env ruby

require 'socket'
require 'fcntl'

client = Socket.new(Socket::pF_INET, Socket::SOCK_STREAM, 0)

flags = client.fcntl(Fcntl::F_GETFL, 0)
client.fcntl(Fcntl::F_SETFL, flags | Fcntl::O_NONBLOCK)
flags = client.fcntl(Fcntl::F_GETFL, 0)

sockaddr = [Socket::AF_INET, 80, 10, 2, 20, 250, ''].pack('snCCCCa8')
client.connect(sockaddr)

client.send("GET something HTTP/1.1\r\n\r\n", 0)
$res = client.readlines
client.close
puts $res


There is no contact with 10.2.20.250:80, and I want the connect call to
return immediately with EINPROGRESS (or similar), so I can use select to
decide how long to wait before giving up (I haven't added the code to do
that since I can't get the connect to return immediately).

As it is now, the connect call hangs for three and a half minutes before
returning "Exception: Connection timed out - connect(2)"

I can successfully do this in C++ on the same machine, so I know it can
work. Am I missing something in the ruby code, or have I misunderstood
something?

I've tried this in ruby 1.6.8 (2002-12-24) [i386-linux] and
ruby 1.8.1 (2003-12-25) [i686-linux], and I'm using Debian GNU/Linux
3.0.

Thanks in advance.

/Henrik Warne
 
N

nobu.nokada

Hi,

At Tue, 7 Sep 2004 00:47:09 +0900,
Henrik Warne wrote in [ruby-talk:111654]:
There is no contact with 10.2.20.250:80, and I want the connect call to
return immediately with EINPROGRESS (or similar), so I can use select to
decide how long to wait before giving up (I haven't added the code to do
that since I can't get the connect to return immediately).

Does this patch help?


Index: ext/socket/socket.c
===================================================================
RCS file: /cvs/ruby/src/ruby/ext/socket/socket.c,v
retrieving revision 1.127
diff -U2 -p -d -r1.127 socket.c
--- ext/socket/socket.c 7 Sep 2004 03:52:14 -0000 1.127
+++ ext/socket/socket.c 7 Sep 2004 06:17:49 -0000
@@ -856,5 +856,7 @@ ruby_connect(fd, sockaddr, len, socks)
{
int status;
+#if defined(HAVE_FCNTL)
int mode;
+#endif
#if WAIT_IN_PROGRESS > 0
int wait_in_progress = -1;
@@ -899,4 +901,7 @@ ruby_connect(fd, sockaddr, len, socks)
#ifdef EINPROGRESS
case EINPROGRESS:
+#endif
+#if defined(HAVE_FCNTL)
+ if (mode & NONBLOCKING) break;
#endif
#if WAIT_IN_PROGRESS > 0
 
H

Henrik Warne

Thanks a lot Nobu, that did the trick! Now it works without problems. Is
this a known problem that will get fixed in a future release, or is it
your own personal fix?

If anybody is interested in the complete solution (including the
time-out using select), let me know, and I'll send the code.

/Henrik Warne

Hi,

At Tue, 7 Sep 2004 00:47:09 +0900,
Henrik Warne wrote in [ruby-talk:111654]:
There is no contact with 10.2.20.250:80, and I want the connect call to
return immediately with EINPROGRESS (or similar), so I can use select to
decide how long to wait before giving up (I haven't added the code to do
that since I can't get the connect to return immediately).

Does this patch help?


Index: ext/socket/socket.c
===================================================================
RCS file: /cvs/ruby/src/ruby/ext/socket/socket.c,v
retrieving revision 1.127
diff -U2 -p -d -r1.127 socket.c
--- ext/socket/socket.c 7 Sep 2004 03:52:14 -0000 1.127
+++ ext/socket/socket.c 7 Sep 2004 06:17:49 -0000
@@ -856,5 +856,7 @@ ruby_connect(fd, sockaddr, len, socks)
{
int status;
+#if defined(HAVE_FCNTL)
int mode;
+#endif
#if WAIT_IN_PROGRESS > 0
int wait_in_progress = -1;
@@ -899,4 +901,7 @@ ruby_connect(fd, sockaddr, len, socks)
#ifdef EINPROGRESS
case EINPROGRESS:
+#endif
+#if defined(HAVE_FCNTL)
+ if (mode & NONBLOCKING) break;
#endif
#if WAIT_IN_PROGRESS > 0
 
N

nobu.nokada

Hi,

At Tue, 7 Sep 2004 23:06:43 +0900,
Henrik Warne wrote in [ruby-talk:111734]:
Thanks a lot Nobu, that did the trick! Now it works without problems. Is
this a known problem that will get fixed in a future release, or is it
your own personal fix?

I think your report would be the first one.
 
H

Henrik Warne

Hi again,

Sorry, but I'm rather new to ruby. How/where do I report this bug so the
fix gets incorporated in later releases of ruby?

/Henrik Warne

Hi,

At Tue, 7 Sep 2004 23:06:43 +0900,
Henrik Warne wrote in [ruby-talk:111734]:
Thanks a lot Nobu, that did the trick! Now it works without problems. Is
this a known problem that will get fixed in a future release, or is it
your own personal fix?

I think your report would be the first one.
 
N

nobu.nokada

Hi,

At Wed, 8 Sep 2004 00:08:36 +0900,
Henrik Warne wrote in [ruby-talk:111746]:
Sorry, but I'm rather new to ruby. How/where do I report this bug so the
fix gets incorporated in later releases of ruby?

Here is enough. Or, post to ruby-core ML.
 

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

Forum statistics

Threads
473,995
Messages
2,570,236
Members
46,822
Latest member
israfaceZa

Latest Threads

Top