Last active
December 31, 2021 02:56
-
-
Save wathenjiang/f2bccc06ccf7852dc9b57e0d97af82a0 to your computer and use it in GitHub Desktop.
gnet_client_nodelay_test
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Dial is like net.Dial(). | |
func (cli *Client) Dial(network, address string) (Conn, error) { | |
c, err := net.Dial(network, address) | |
if err != nil { | |
return nil, err | |
} | |
defer c.Close() | |
sc, ok := c.(syscall.Conn) | |
if !ok { | |
return nil, errors.New("failed to convert net.Conn to syscall.Conn") | |
} | |
rc, err := sc.SyscallConn() | |
if err != nil { | |
return nil, errors.New("failed to get syscall.RawConn from net.Conn") | |
} | |
var DupFD int | |
e := rc.Control(func(fd uintptr) { | |
DupFD, err = unix.Dup(int(fd)) // 利用闭包修改了 err | |
}) | |
if err != nil { | |
return nil, err | |
} | |
if e != nil { | |
return nil, e | |
} | |
if strings.HasPrefix(network, "tcp") { | |
value, err := unix.GetsockoptUint64(DupFD, unix.IPPROTO_TCP, unix.TCP_NODELAY) | |
if err != nil { | |
fmt.Println(err.Error()) | |
return nil, err | |
} | |
fmt.Println("before set value: ", value) | |
if cli.opts.TCPNoDelay == TCPDelay { | |
if err = socket.SetNoDelay(DupFD, 0); err != nil { | |
return nil, err | |
} | |
} | |
value, err = unix.GetsockoptUint64(DupFD, unix.IPPROTO_TCP, unix.TCP_NODELAY) | |
if err != nil { | |
fmt.Println(err.Error()) | |
return nil, err | |
} | |
fmt.Println("after set value: ", value) | |
if cli.opts.TCPKeepAlive > 0 { | |
if err = socket.SetKeepAlive(DupFD, int(cli.opts.TCPKeepAlive/time.Second)); err != nil { | |
return nil, err | |
} | |
} | |
} | |
if cli.opts.SocketSendBuffer > 0 { | |
if err = socket.SetSendBuffer(DupFD, cli.opts.SocketSendBuffer); err != nil { | |
return nil, err | |
} | |
} | |
if cli.opts.SocketRecvBuffer > 0 { | |
if err = socket.SetRecvBuffer(DupFD, cli.opts.SocketRecvBuffer); err != nil { | |
return nil, err | |
} | |
} | |
var ( | |
sockAddr unix.Sockaddr | |
gc Conn | |
) | |
switch c.(type) { | |
case *net.UnixConn: | |
if sockAddr, _, _, err = socket.GetUnixSockAddr(c.RemoteAddr().Network(), c.RemoteAddr().String()); err != nil { | |
return nil, err | |
} | |
ua := c.LocalAddr().(*net.UnixAddr) | |
ua.Name = c.RemoteAddr().String() + "." + strconv.Itoa(DupFD) | |
gc = newTCPConn(DupFD, cli.el, sockAddr, cli.opts.Codec, c.LocalAddr(), c.RemoteAddr()) | |
case *net.TCPConn: | |
if sockAddr, _, _, _, err = socket.GetTCPSockAddr(c.RemoteAddr().Network(), c.RemoteAddr().String()); err != nil { | |
return nil, err | |
} | |
gc = newTCPConn(DupFD, cli.el, sockAddr, cli.opts.Codec, c.LocalAddr(), c.RemoteAddr()) | |
case *net.UDPConn: | |
if sockAddr, _, _, _, err = socket.GetUDPSockAddr(c.RemoteAddr().Network(), c.RemoteAddr().String()); err != nil { | |
return nil, err | |
} | |
gc = newUDPConn(DupFD, cli.el, c.LocalAddr(), sockAddr, true) | |
default: | |
return nil, gerrors.ErrUnsupportedProtocol | |
} | |
err = cli.el.poller.UrgentTrigger(cli.el.register, gc) | |
if err != nil { | |
gc.Close() | |
return nil, err | |
} | |
return gc, nil | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment