* [Caml-list] Unix.connect for non-blocking sockets on Windows
@ 2012-09-14 13:53 Romain Bardou
2012-09-14 14:27 ` Jérémie Dimino
0 siblings, 1 reply; 7+ messages in thread
From: Romain Bardou @ 2012-09-14 13:53 UTC (permalink / raw)
To: caml-list
Hello,
It seems, from the manual[1] that sockets of the Unix module are fully
implemented on Windows. It also seems, from other googling, that
non-blocking sockets are also implemented.
[1] http://caml.inria.fr/pub/docs/manual-ocaml/manual036.html
However, when I run the Unix.connect command on Windows, I get:
Unix_error(EWOULDBLOCK, "connect", "")
I'm using OCaml 3.12.1 on Windows using the (older) installer from
Jonathan, which uses mingw if I'm not mistaken. The code I use is more
or less equivalent to:
open Unix
let address = "xxx.xxx.xxx.xxx" in (* some IP for IPv4 *)
let port = 9543 in
let fd = socket PF_INET SOCK_STREAM 0 in
set_nonblock fd;
connect fd (ADDR_INET (Unix.inet_addr_of_string address, port))
Is this a known issue?
Thanks,
--
Romain Bardou
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Caml-list] Unix.connect for non-blocking sockets on Windows
2012-09-14 13:53 [Caml-list] Unix.connect for non-blocking sockets on Windows Romain Bardou
@ 2012-09-14 14:27 ` Jérémie Dimino
2012-09-14 15:21 ` Jerome Vouillon
0 siblings, 1 reply; 7+ messages in thread
From: Jérémie Dimino @ 2012-09-14 14:27 UTC (permalink / raw)
To: Romain Bardou; +Cc: caml-list
Hi,
Le Fri, 14 Sep 2012 15:53:24 +0200,
Romain Bardou <romain.bardou@inria.fr> a écrit :
> open Unix
> let address = "xxx.xxx.xxx.xxx" in (* some IP for IPv4 *)
> let port = 9543 in
> let fd = socket PF_INET SOCK_STREAM 0 in
> set_nonblock fd;
> connect fd (ADDR_INET (Unix.inet_addr_of_string address, port))
If the socket is in non-blocking mode and connect blocks, then you get
a Unix.EWOULDBLOCK error. According to the MSDN documentation, if
connect fails with EWOULDBLOCK, you have to wait for the socket to
become writeable then call connect again which will fail with EISCONN
if the connection succeeded.
--
Jérémie
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Caml-list] Unix.connect for non-blocking sockets on Windows
2012-09-14 14:27 ` Jérémie Dimino
@ 2012-09-14 15:21 ` Jerome Vouillon
2012-09-14 15:26 ` Romain Bardou
2012-09-14 15:33 ` Jérémie Dimino
0 siblings, 2 replies; 7+ messages in thread
From: Jerome Vouillon @ 2012-09-14 15:21 UTC (permalink / raw)
To: Romain Bardou; +Cc: caml-list, Jérémie Dimino
Hi Jérémie,
On Fri, Sep 14, 2012 at 04:27:17PM +0200, Jérémie Dimino wrote:
> Le Fri, 14 Sep 2012 15:53:24 +0200,
> Romain Bardou <romain.bardou@inria.fr> a écrit :
>
> > open Unix
> > let address = "xxx.xxx.xxx.xxx" in (* some IP for IPv4 *)
> > let port = 9543 in
> > let fd = socket PF_INET SOCK_STREAM 0 in
> > set_nonblock fd;
> > connect fd (ADDR_INET (Unix.inet_addr_of_string address, port))
>
> If the socket is in non-blocking mode and connect blocks, then you get
> a Unix.EWOULDBLOCK error. According to the MSDN documentation, if
> connect fails with EWOULDBLOCK, you have to wait for the socket to
> become writeable then call connect again which will fail with EISCONN
> if the connection succeeded.
This is not quite what I can read in the MSDN documentation...
"[...] it is not recommended that applications use multiple calls to
connect to detect connection completion. If they do, they must be
prepared to handle WSAEINVAL and WSAEWOULDBLOCK error values the
same way that they handle WSAEALREADY, to assure robust operation"
You should use Unix.getsockopt_error (just like under Unix) to check
for errors when the socket becomes writable, rather than call connect
again.
-- Jérôme
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Caml-list] Unix.connect for non-blocking sockets on Windows
2012-09-14 15:21 ` Jerome Vouillon
@ 2012-09-14 15:26 ` Romain Bardou
2012-09-14 15:33 ` Jérémie Dimino
1 sibling, 0 replies; 7+ messages in thread
From: Romain Bardou @ 2012-09-14 15:26 UTC (permalink / raw)
To: Jerome Vouillon; +Cc: caml-list, Jérémie Dimino
Le 14/09/2012 17:21, Jerome Vouillon a écrit :
> Hi Jérémie,
>
> On Fri, Sep 14, 2012 at 04:27:17PM +0200, Jérémie Dimino wrote:
>> Le Fri, 14 Sep 2012 15:53:24 +0200,
>> Romain Bardou<romain.bardou@inria.fr> a écrit :
>>
>>> open Unix
>>> let address = "xxx.xxx.xxx.xxx" in (* some IP for IPv4 *)
>>> let port = 9543 in
>>> let fd = socket PF_INET SOCK_STREAM 0 in
>>> set_nonblock fd;
>>> connect fd (ADDR_INET (Unix.inet_addr_of_string address, port))
>>
>> If the socket is in non-blocking mode and connect blocks, then you get
>> a Unix.EWOULDBLOCK error. According to the MSDN documentation, if
>> connect fails with EWOULDBLOCK, you have to wait for the socket to
>> become writeable then call connect again which will fail with EISCONN
>> if the connection succeeded.
>
> This is not quite what I can read in the MSDN documentation...
>
> "[...] it is not recommended that applications use multiple calls to
> connect to detect connection completion. If they do, they must be
> prepared to handle WSAEINVAL and WSAEWOULDBLOCK error values the
> same way that they handle WSAEALREADY, to assure robust operation"
>
> You should use Unix.getsockopt_error (just like under Unix) to check
> for errors when the socket becomes writable, rather than call connect
> again.
Oh so actually it's even easier than I thought. From what you're saying
I just need to treat the EWOULDBLOCK case as if it was EINPROGRESS
(which is what is returned by connect on Linux) and the rest is the same.
Thanks to both of you!
--
Romain Bardou
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Caml-list] Unix.connect for non-blocking sockets on Windows
2012-09-14 15:21 ` Jerome Vouillon
2012-09-14 15:26 ` Romain Bardou
@ 2012-09-14 15:33 ` Jérémie Dimino
2012-09-14 15:46 ` Romain Bardou
2012-10-10 14:14 ` Jerome Vouillon
1 sibling, 2 replies; 7+ messages in thread
From: Jérémie Dimino @ 2012-09-14 15:33 UTC (permalink / raw)
To: Jerome Vouillon; +Cc: Romain Bardou, caml-list
Le Fri, 14 Sep 2012 17:21:25 +0200,
Jerome Vouillon <Jerome.Vouillon@pps.jussieu.fr> a écrit :
> You should use Unix.getsockopt_error (just like under Unix) to check
> for errors when the socket becomes writable, rather than call connect
> again.
Acutally, last time i tried (on Windows XP) it was not working,
Unix.getsockopt_error was returning None but the socket was not
connected.
--
Jérémie
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Caml-list] Unix.connect for non-blocking sockets on Windows
2012-09-14 15:33 ` Jérémie Dimino
@ 2012-09-14 15:46 ` Romain Bardou
2012-10-10 14:14 ` Jerome Vouillon
1 sibling, 0 replies; 7+ messages in thread
From: Romain Bardou @ 2012-09-14 15:46 UTC (permalink / raw)
To: Jérémie Dimino; +Cc: Jerome Vouillon, caml-list
Le 14/09/2012 17:33, Jérémie Dimino a écrit :
> Le Fri, 14 Sep 2012 17:21:25 +0200,
> Jerome Vouillon<Jerome.Vouillon@pps.jussieu.fr> a écrit :
>
>> You should use Unix.getsockopt_error (just like under Unix) to check
>> for errors when the socket becomes writable, rather than call connect
>> again.
>
> Acutally, last time i tried (on Windows XP) it was not working,
> Unix.getsockopt_error was returning None but the socket was not
> connected.
>
I just tried it (on Windows XP) and it works. But the connection is very
slow for some reason, with about 30s between each message. I probably
have to flush the socket or something.
Cheers,
--
Romain
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Caml-list] Unix.connect for non-blocking sockets on Windows
2012-09-14 15:33 ` Jérémie Dimino
2012-09-14 15:46 ` Romain Bardou
@ 2012-10-10 14:14 ` Jerome Vouillon
1 sibling, 0 replies; 7+ messages in thread
From: Jerome Vouillon @ 2012-10-10 14:14 UTC (permalink / raw)
To: Jérémie Dimino; +Cc: caml-list
On Fri, Sep 14, 2012 at 05:33:50PM +0200, Jérémie Dimino wrote:
> Le Fri, 14 Sep 2012 17:21:25 +0200,
> Jerome Vouillon <Jerome.Vouillon@pps.jussieu.fr> a écrit :
>
> > You should use Unix.getsockopt_error (just like under Unix) to check
> > for errors when the socket becomes writable, rather than call connect
> > again.
>
> Actually, last time i tried (on Windows XP) it was not working,
> Unix.getsockopt_error was returning None but the socket was not
> connected.
I believe that this is due to a bug in the implementation of
Unix.select ( http://caml.inria.fr/mantis/view.php?id=5783 ). As a
result, this function returns immediately and wrongly reports that
the socket is writable. (Since OCaml 4, this bug only occurs when
simultaneously selecting a non-socket file descriptor.)
Thus, calling Unix.connect again instead of Unix.getsockopt_error is
just a workaround for this bug: you are busy waiting for the
connection to complete. (And, by the way, the secont call to
Unix.connect will fail with the error code EALREADY rather that
EWOULDBLOCK with Windows 8.)
-- Jerome
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2012-10-10 14:15 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-09-14 13:53 [Caml-list] Unix.connect for non-blocking sockets on Windows Romain Bardou
2012-09-14 14:27 ` Jérémie Dimino
2012-09-14 15:21 ` Jerome Vouillon
2012-09-14 15:26 ` Romain Bardou
2012-09-14 15:33 ` Jérémie Dimino
2012-09-14 15:46 ` Romain Bardou
2012-10-10 14:14 ` Jerome Vouillon
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox