Bootstrap

golang 非正常退出信号捕捉处理

最近用golang写一个P2P程序,发现在安卓(arm linux )环境下按ctrl+c退出程序,占用udp端口不会在程序退出后自动释放

而普通x86/x64 Linux和win 不会出现这种情况

查阅资料 可以通过捕捉信号处理。

os.Interrupt(即syscall.SIGINT, Ctrl+C 产生)

os.Kill(即syscall.SIGKILL, 程序关闭产生,调试中还没捕获到过)

syscall.SIGTERM(kill 或者killall 产生)

修改程序,捕捉到信号通过chan传入exitHandle关闭处理

测试代码如下

package main

import (
	"fmt"
	"net"
	"os"
	"os/signal"
	"syscall"
)

var exitChan chan os.Signal
var listener *net.UDPConn

func exitHandle() {

	s := <-exitChan
	fmt.Println("收到退出信号", s)

	if listener != nil {
		listener.Close()
		fmt.Println("关闭listener")

	}
	os.Exit(1) //如果ctrl+c 关不掉程序,使用os.Exit强行关掉
}

func main() {

	exitChan = make(chan os.Signal)
	signal.Notify(exitChan, os.Interrupt, os.Kill, syscall.SIGTERM)
	go exitHandle()
	var err error
	listener, err = net.ListenUDP("udp", &net.UDPAddr{IP: net.IPv4zero, Port: 12345})
	if err != nil {
		panic(err)
		return
	}
	defer func() {
		fmt.Println("ctrl + c 退出不会执行到这里")
		listener.Close()
	}()

	//main body code
	for {
		data := make([]byte, 1024)
		n, remoteAddr, err := listener.ReadFromUDP(data)
		if err != nil {
			fmt.Printf("error during read: %s", err)
		}
		message := string(data[:n])
		fmt.Printf("receive:[%s]  from:%s:%d\r\n", message, remoteAddr.IP.String(), remoteAddr.Port)
	}

}

 

 linux可以使用kill -l 来查看当前系统的信号类型:
 1) SIGHUP       2) SIGINT       3) SIGQUIT      4) SIGILL       5) SIGTRAP
 6) SIGABRT      7) SIGBUS       8) SIGFPE       9) SIGKILL     10) SIGUSR1
11) SIGSEGV     12) SIGUSR2     13) SIGPIPE     14) SIGALRM     15) SIGTERM
16) SIGSTKFLT   17) SIGCHLD     18) SIGCONT     19) SIGSTOP     20) SIGTSTP
21) SIGTTIN     22) SIGTTOU     23) SIGURG      24) SIGXCPU     25) SIGXFSZ
26) SIGVTALRM   27) SIGPROF     28) SIGWINCH    29) SIGIO       30) SIGPWR
31) SIGSYS      34) SIGRTMIN    35) SIGRTMIN+1  36) SIGRTMIN+2  37) SIGRTMIN+3
38) SIGRTMIN+4  39) SIGRTMIN+5  40) SIGRTMIN+6  41) SIGRTMIN+7  42) SIGRTMIN+8
43) SIGRTMIN+9  44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9  56) SIGRTMAX-8  57) SIGRTMAX-7
58) SIGRTMAX-6  59) SIGRTMAX-5  60) SIGRTMAX-4  61) SIGRTMAX-3  62) SIGRTMAX-2
63) SIGRTMAX-1  64) SIGRTMAX

 

1:  "hangup",
2:  "interrupt",
3:  "quit",
4:  "illegal instruction",
5:  "trace/breakpoint trap",
6:  "aborted",
7:  "bus error",
8:  "floating point exception",
9:  "killed",
10: "user defined signal 1",
11: "segmentation fault",
12: "user defined signal 2",
13: "broken pipe",
14: "alarm clock",
15: "terminated",

悦读

道可道,非常道;名可名,非常名。 无名,天地之始,有名,万物之母。 故常无欲,以观其妙,常有欲,以观其徼。 此两者,同出而异名,同谓之玄,玄之又玄,众妙之门。

;