Issue #12033 has been updated by Usaku NAKAMURA.


First, You don't have to care about initializing/cleanup WinSock.
Ruby does them.

To keep source level compatibility with Unix-like platforms,
Ruby makes some hack about Windows' socket.
The return value of Unix's `socket` is a file descriptor.
Therefore Ruby on Windows replaces WinSock's `socket` to return a file descriptor
instead of to return a SOCKET.
Same as `socket`, `bind` is also replaced by Ruby to accept a file descriptor instead of
a SOCKET.

But Ruby does not replace `WSASocket` because it doesn't exist on Unix.
So, `WSASocket` returns a SOCKET, and `bind` doesn't accept it because it's not a file descriptor.

If you really want to use `WSASocket` and `bind` in your extension, you can use
`rb_w32_wrap_io_handle` and `rb_w32_unwrap_io_handle` API.
But, anyway, you have to read and learn the implementation of Ruby on Windows :-P

----------------------------------------
Bug #12033: WSASocket can't work with Ruby extensions.
https://bugs.ruby-lang.org/issues/12033#change-56780

* Author: Nicolas Noble
* Status: Open
* Priority: Normal
* Assignee: Nobuyoshi Nakada
* ruby -v: ruby 2.2.3p173 (2015-08-18 revision 51636) [x64-mingw32]
* Backport: 2.0.0: UNKNOWN, 2.1: UNKNOWN, 2.2: UNKNOWN, 2.3: UNKNOWN
----------------------------------------
Basically, when creating a gem with C code that tries to do a WSASocket() call, the socket will end up being non-viable. I have tried this using the native DevKit compiler, rake-compiler-dock, ruby 2.2, 2.1, 32 and 64 bits, to no avail. If a C extension calls into socket(), that socket will work, but if it calls into WSASocket(), it somehow won't.

I have attached an example of a very simple gem, which is basically the sample code from https://msdn.microsoft.com/en-us/library/windows/desktop/ms737550(v=vs.85).aspx

In the first test, calling into socket() and binding that socket to localhost will work. In the second test, calling into WSASocket() will return a socket, but then binding it won't work, with a WSAENOTSOCK error.

If you add a main() function that simply calls into the Init_foobar() function, and compile it into a normal exe file, both tests will work normally.


My guess is that the ruby environment is doing something... weird ? And as a result, the winsock system is altered in a way that makes WSASocket unviable.

---Files--------------------------------
foobar.zip (2.68 KB)


-- 
https://bugs.ruby-lang.org/

Unsubscribe: <mailto:ruby-core-request / ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>