/
counter_atomic.go
62 lines (52 loc) · 1.25 KB
/
counter_atomic.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
// counter.go: simple race detection example
package main
import (
"fmt"
"io"
"log"
"net"
"sync/atomic"
)
type Server struct {
conn net.Listener
numClients int64
}
// NewServer creates a new Server that will listen on the specified proot/addr combo.
// See net.Dial for documentation on proto and addr.
func NewServer(proto, addr string) (*Server, error) {
conn, err := net.Listen(proto, addr)
if err != nil {
return nil, err
}
return &Server{conn: conn}, nil
}
// Serve makes Server listen for incoming connection, and spawn a goroutine calling handleClient
// for each new connection.
func (srv *Server) Serve() {
for {
conn, err := srv.conn.Accept()
if err != nil {
log.Print(err)
return
}
atomic.AddInt64(&srv.numClients, 1)
go srv.handleClient(conn)
}
}
func (srv *Server) Close() {
srv.conn.Close()
}
// handleClient manages the communication with a single client.
// In this example, we just send a predefined message and close the door
func (srv *Server) handleClient(conn net.Conn) {
nc := srv.numClients
io.WriteString(conn, fmt.Sprintf("Ciao, sei il client #%d che si connette a me\n", nc))
conn.Close()
}
func main() {
srv, err := NewServer("tcp", "localhost:2380")
if err != nil {
log.Fatal(err)
}
srv.Serve()
}