Skip to content
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

[Bug]: UDP Port Not Released After Stopping Server #675

Open
3 tasks done
wang229819838 opened this issue Jan 13, 2025 · 0 comments
Open
3 tasks done

[Bug]: UDP Port Not Released After Stopping Server #675

wang229819838 opened this issue Jan 13, 2025 · 0 comments
Assignees
Labels
bug Something isn't working

Comments

@wang229819838
Copy link

Actions I've taken before I'm here

  • I've thoroughly read the documentations on this issue but still have no clue.
  • I've searched the Github Issues but didn't find any duplicate issues that have been resolved.
  • I've searched the internet for this issue but didn't find anything helpful.

What happened?

I am experiencing an issue where the UDP port is not being released after stopping the server using Gnet (versions v2.5.0 and v2.7.0). Even though I have correctly called the shutdown method and verified that the server has stopped, the UDP port continues to be in use.

Steps to Reproduce:
Start a UDP server using Gnet on a specific port (e.g., 40119).
Stop the server using gnet.Server.Stop() or similar shutdown logic.
Check the port using ss -unlap or lsof to confirm that the port is still being used.
The port remains in the "UNCONN" state with the associated process still holding the file descriptor.

Major version of gnet

v2

Specific version of gnet

v2.5.0 or v2.7.0

Operating system

Linux

OS version

Linux 4.18.0-305.3.1.el8.x86_64 x86_64

Go version

go version go1.22.0 darwin/amd64

Relevant log output

[root@localhost ~]# ./t17 
2025/01/13 23:57:05 Starting UDP server on port 9000...
[gnet] 2025-01-13T23:57:05.950384672+08:00      INFO    logging/logger.go:256   Launching gnet with 1 event-loops, listening on: udp://:9000
2025/01/13 23:57:35 Starting UDP server on port 9001...
[gnet] 2025-01-13T23:57:35.978831388+08:00      INFO    logging/logger.go:256   Launching gnet with 1 event-loops, listening on: udp://:9001
2025/01/13 23:58:05 Starting UDP server on port 9002...
[gnet] 2025-01-13T23:58:05.988608289+08:00      INFO    logging/logger.go:256   Launching gnet with 1 event-loops, listening on: udp://:9002
2025/01/13 23:58:36 Starting UDP server on port 9003...
[gnet] 2025-01-13T23:58:36.017881512+08:00      INFO    logging/logger.go:256   Launching gnet with 1 event-loops, listening on: udp://:9003
2025/01/13 23:59:06 Starting UDP server on port 9004...
[gnet] 2025-01-13T23:59:06.047029878+08:00      INFO    logging/logger.go:256   Launching gnet with 1 event-loops, listening on: udp://:9004
2025/01/13 23:59:36 Starting UDP server on port 9005...
[gnet] 2025-01-13T23:59:36.076213127+08:00      INFO    logging/logger.go:256   Launching gnet with 1 event-loops, listening on: udp://:9005
2025/01/14 00:00:06 Starting UDP server on port 9006...
[gnet] 2025-01-14T00:00:06.10547833+08:00       INFO    logging/logger.go:256   Launching gnet with 1 event-loops, listening on: udp://:9006
2025/01/14 00:00:36 Starting UDP server on port 9007...
[gnet] 2025-01-14T00:00:36.13464632+08:00       INFO    logging/logger.go:256   Launching gnet with 1 event-loops, listening on: udp://:9007
2025/01/14 00:01:06 Starting UDP server on port 9008...
[gnet] 2025-01-14T00:01:06.163904466+08:00      INFO    logging/logger.go:256   Launching gnet with 1 event-loops, listening on: udp://:9008

[root@localhost ~]# ss -unlap
State         Recv-Q        Send-Q               Local Address:Port               Peer Address:Port       Process                                  
UNCONN        0             0                                *:9000                          *:*           users:(("t17",pid=559102,fd=3))         
UNCONN        0             0                                *:9001                          *:*           users:(("t17",pid=559102,fd=9))         
UNCONN        0             0                                *:9002                          *:*           users:(("t17",pid=559102,fd=12))        
UNCONN        0             0                                *:9003                          *:*           users:(("t17",pid=559102,fd=15))        
UNCONN        0             0                                *:9004                          *:*           users:(("t17",pid=559102,fd=18))        
UNCONN        0             0                                *:9005                          *:*           users:(("t17",pid=559102,fd=21))        
UNCONN        0             0                                *:9006                          *:*           users:(("t17",pid=559102,fd=24))

Code snippets (optional)

package main

import (
	"context"
	"flag"
	"fmt"
	"log"
	"time"

	"github.com/panjf2000/gnet/v2"
)

type echoServer struct {
	gnet.BuiltinEventEngine
	eng gnet.Engine
}

func (es echoServer) OnBoot(eng gnet.Engine) (action gnet.Action) {
	es.eng = eng
	return
}
func (es *echoServer) OnTraffic(c gnet.Conn) gnet.Action {
	data, _ := c.Next(-1)
	c.Write(data)
	return gnet.None
}

func main() {
	var port int
	var multicore, reuseport bool

	// Example command: go run echo.go --port 9000 --multicore=false --reuseport=false
	flag.IntVar(&port, "port", 9000, "--port 9000")
	flag.BoolVar(&multicore, "multicore", false, "--multicore true")
	flag.BoolVar(&reuseport, "reuseport", false, "--reuseport true")
	flag.Parse()

	var currentServer *echoServer

	// Start UDP server every 30 seconds
	go func() {
		for {
			// Stop the current server if it exists
			if currentServer != nil {
				if err := currentServer.eng.Stop(context.Background()); err != nil {
					log.Printf("Error stopping server on port %d: %v\n", port, err)
				} else {
					log.Printf("Server on port %d stopped.\n", port)
				}
			}

			// Create and start a new server
			echo := new(echoServer)
			addr := fmt.Sprintf("udp://:%d", port)
			log.Printf("Starting UDP server on port %d...\n", port)
			go func() {
				// Run new server
				err := gnet.Run(echo, addr, gnet.WithMulticore(multicore), gnet.WithReusePort(reuseport))
				if err != nil {
					log.Printf("Failed to start server on port %d: %v\n", port, err)
				} else {
					currentServer = echo // Keep reference to the current server
				}
			}()

			port++                       // Increment the port number
			time.Sleep(30 * time.Second) // Wait for 30 seconds before starting next server
		}
	}()

	// Block main goroutine indefinitely to keep servers running
	select {}
}

How to Reproduce

1、CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags "-w -s"
2、./app
3、ss -unlap

Does this issue reproduce with the latest release?

It can reproduce with the latest release

@wang229819838 wang229819838 added the bug Something isn't working label Jan 13, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants