Hi,
On Tue, Aug 21, 2012 at 10:29 PM, Ondekoza <
onde...@gmail.com> wrote:
> I have a function that is listening on a port for incoming UDP packets.
> It works fine. Unfortunately it reserves the port exclusively, so that
> another application
> that wants to listen to the same port will fail to start.
It seems like original net package designers did implement
"please don't do that" things as a set of API.
If you can try attached then you'll see:
- first-come-first-serve behavior on BSD variants,
- last-come-first-serve behavior on linux.
-- Mikio
--
package main
import (
"fmt"
"log"
"os"
"syscall"
"time"
)
func main() {
s, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_DGRAM, 0)
if err != nil {
log.Fatal(err)
}
syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_REUSEADDR, 1)
syscall.SetsockoptInt(s, syscall.SOL_SOCKET,
syscall.SO_REUSEPORT, 1) // remove this line when you run linux
lsa := &syscall.SockaddrInet4{Port: 12345}
err = syscall.Bind(s, lsa)
if err != nil {
log.Fatal(err)
}
syscall.SetNonblock(s, true)
rsa := &syscall.SockaddrInet4{Port: 12345, Addr: [4]byte{127, 0, 0, 1}}
fin, ack := make(chan bool), make(chan bool)
go reader(s, fin, ack)
for i := 0; i < 30; i++ {
time.Sleep(time.Second)
syscall.Sendto(s, []byte(fmt.Sprintf("%v",
os.Getpid())), 0, rsa)
}
fin <- true
<-ack
fmt.Println("\nbye then")
}
func reader(s int, fin <-chan bool, ack chan<- bool) {
rb := make([]byte, 32)
for {
n, _, err := syscall.Recvfrom(s, rb, 0)
if err != nil {
time.Sleep(time.Second)
} else {
// Let's see who is the winner
fmt.Print(string(rb[:n]), " ")
}
select {
case <-fin:
ack <- true
return
default:
}
}
}