Files
v2ray_simple/netLayer/listen.go
hahahrfool 2c9c993c11 修订文档、示例; 修复在windows上直连时readv闪退的bug;
这次在程序ctrl+C关闭时, 会主动Close所有的监听端口. 主要是被报告windows有时退出程序之后, 端口还是处于占用状态.

试图引进新的 Makefile_release 文件 以及新的workflow文件 来快速编译发布包
2022-04-03 14:32:23 +08:00

94 lines
2.5 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package netLayer
import (
"net"
"os"
"strings"
"time"
"github.com/hahahrfool/v2ray_simple/utils"
"go.uber.org/zap"
)
func loopAccept(listener net.Listener, acceptFunc func(net.Conn)) {
for {
newc, err := listener.Accept()
if err != nil {
errStr := err.Error()
if strings.Contains(errStr, "closed") {
if ce := utils.CanLogDebug("local connection closed"); ce != nil {
ce.Write(zap.Error(err))
}
break
}
if ce := utils.CanLogWarn("failed to accept connection"); ce != nil {
ce.Write(zap.Error(err))
}
if strings.Contains(errStr, "too many") {
if ce := utils.CanLogWarn("To many incoming conn! Will Sleep."); ce != nil {
ce.Write(zap.String("err", errStr))
}
time.Sleep(time.Millisecond * 500)
}
continue
}
go acceptFunc(newc)
}
}
// ListenAndAccept 试图监听 所有类型的网络包括tcp, udp 和 unix domain socket.
//
// 非阻塞在自己的goroutine中监听.
func ListenAndAccept(network, addr string, acceptFunc func(net.Conn)) (listener net.Listener, err error) {
switch network {
case "udp", "udp4", "udp6":
var ua *net.UDPAddr
ua, err = net.ResolveUDPAddr("udp", addr)
if err != nil {
return
}
listener, err = NewUDPListener(ua)
if err != nil {
return
}
go loopAccept(listener, acceptFunc)
case "unix":
// 参考 https://eli.thegreenplace.net/2019/unix-domain-sockets-in-go/
//监听 unix domain socket后就会自动创建 相应文件;
// 而且程序退出后,该文件不会被删除
// 而且再次启动后如果遇到了这个文件就会报错就像tcp端口已经被监听 的错误一样:
// “bind: address already in use”
// 所以必须把原文件删掉
// 但是问题是,有可能被一些粗心的用户搞出大问题
// 如果不小心设置成了 '/' 根目录,那我们删的话是不是会直接把所有文件都删掉了?
// 总之RemoveAll函数千万不能用Remove函数倒是没什么大事
if utils.FileExist(addr) {
if ce := utils.CanLogDebug("unix file exist"); ce != nil {
//log.Println("unix file exist, deleting", addr)
ce.Write(zap.String("deleting", addr))
}
err = os.Remove(addr)
if err != nil {
err = utils.ErrInErr{ErrDesc: "Error when deleting previous unix socket file,", ErrDetail: err, Data: addr}
return
}
}
fallthrough
default:
if network == "" {
network = "tcp"
}
listener, err = net.Listen(network, addr)
if err != nil {
return
}
go loopAccept(listener, acceptFunc)
}
return
}