-
Notifications
You must be signed in to change notification settings - Fork 18k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
net: File method of Conn on Windows #10350
Comments
See #9503. We need a good compromise for both issues, and so need Windows experts. |
I don't think you can have "if windows then just return c.fd" option, because it is not what (*conn).File documented to do. Why do you need access to Windows socket handle? Alex |
Excuse me for discuss, because we want to pass socket handle into external process for listening. For example, to implement graceful server, we often use fork/exec model. |
In my case, I am passing it to some c compiled with cgo for additional
|
@vyrus001 there is no way to access original socket. If you need that functionality, you have to make copy of main Go repo and make whatever changes you want to net package. @mattn I am not sure what you require, but have you tried implementing windows version of (*netFD).dup? Just use syscall.DuplicateHandle. Would that work for you? Alex |
|
Fair enough. Use WSADuplicateSocket instead. Would that work for you? Alex |
Works fine. (But not enough to do that I want) Look this: https://github.com/mattn/gospel/blob/master/example/echo-server.go This is not possible to build currently. For building, it need https://codereview.appspot.com/177590043/ This is fork/exec model server. This can replace executable without stop server with SIGHUP. This package is passing socket handle into child process on windows. |
@mattn your old CL needs to be moved into Gerrit and made work on tip before we can discuss it. Alex |
CL https://golang.org/cl/8683 mentions this issue. |
…tConn, FileListener DO NOT REVIEW Fixes golang#9503. Fixes golang#10350. Change-Id: If0851cb3340281cc1ea523cd0ddf48fc7f87c775
Gah, I just ran into this as well: If there is no way to get a underlying socket fd, I'm probably at a dead end golang-wise :( |
This issue might be unfixable because of the architectural differences between Unix-variants and Windows. One good news is that Go 1.12 supports #24331; you may use os.File.SyscallConn instead of File method of net.{TCP,UDP,IP}Conn. |
The purpose of this issue is to get the handle of a The |
The purpose of the File method is not only for tweaking/crafting the underlying socket but for passing a cloned descriptor pointing to the same underlying socket to external processes. |
I can see that it would not be fixable with the current API (due to dupe guarantees/etc.), but certainly would be nice and useful for many reasons. It's a bit of a shame that the API kind of tosses Windows out the the uh... window here. |
@mikioh package main
/*
#cgo LDFLAGS: -lWs2_32
#include <stdio.h>
#include <Winsock.h>
void get_listen_addr(SOCKET s) {
struct sockaddr_in name;
int namelen = sizeof(name);
if (getsockname(s, (struct sockaddr*)&name, &namelen)) {
printf("failed %d\n", WSAGetLastError());
return;
}
printf("%hhu.%hhu.%hhu.%hhu:%hu\n",
name.sin_addr.S_un.S_un_b.s_b1,
name.sin_addr.S_un.S_un_b.s_b2,
name.sin_addr.S_un.S_un_b.s_b3,
name.sin_addr.S_un.S_un_b.s_b4,
ntohs(name.sin_port));
}
*/
import "C"
import "net"
func main() {
listener, err := net.Listen("tcp4", "127.0.0.88:0")
if err != nil {
panic(err)
}
defer listener.Close()
rawConn, err := listener.(*net.TCPListener).SyscallConn()
if err != nil {
panic(err)
}
fdCh := make(chan uintptr, 1)
err = rawConn.Control(func(fd uintptr) {
fdCh <- fd
})
if err != nil {
panic(err)
}
fd := <-fdCh
// You can do anything with the fd now
println(listener.Addr().String())
C.get_listen_addr(C.SOCKET(fd))
} The handle can also be passed to external processes with
But this approach is not worse than |
Any progress on this issue?
So is there any workaround? |
As the documentation says, when the f function returns, won't the obtained handle be invalidated? |
No, the handle won't be invalidated. |
The problem here is not how to get the handle, which is solved by This is the same problem as the dangling pointer. |
Thank you very much, I now use the go coroutine and chan to make f blocked, so that the handle is always valid. When the user code closes, f is returned through the synchronized chan, the code is similar to the following, I don't know if this is the best practice in this way? func (s *struct) getFd() {
fdCh := make(chan uintptr, 1)
s.syncClose = make(chan int)
go func() {
s.rawConn.Control(func(fd uintptr) {
fdCh <- fd
<-s.syncClose
})
}()
s.fd = <-fdCh
}
func (s *struct) close() error {
s.syncClose <- 1
} |
I am writing something that requires access to the file descriptor of a socket created by net.Dial (which returns a net.conn) and then recast as net.TCPConn so that I can use net.TCPConn.File().Fd().
However, (as the error message says), "dup is not supported on windows". for my purposes, I don't "need" the dup() and would love to settle for just getting the raw file descriptor, but sadly the code within conn.File() appears as follows.
https://golang.org/src/net/net.go?s=5510:5555#L195
Is there any way I could ask for an "if windows then just return c.fd" option? Hopefully this request isn't a waste of time, I am far from an expert on go.
The text was updated successfully, but these errors were encountered: