-
Notifications
You must be signed in to change notification settings - Fork 1
/
socket_server.go
116 lines (101 loc) · 2.98 KB
/
socket_server.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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
package main
import (
"encoding/binary"
"fmt"
"github.com/coraldane/monitor-tool/conf"
"github.com/coraldane/toolkits/encode"
"log"
"net"
"os"
"runtime"
"sync"
"time"
)
const (
CONNECTION_MAX = 1024
)
var (
poolLock sync.RWMutex
poolClient map[string]*ClientInfo
)
type ClientInfo struct {
AssignId string
Conn net.Conn //The TCP/IP connectin to the player.
GmtConnect time.Time //The time connect with server.
ClientType string
HostIp string
HostPort string
ClientIp string
ClientPort string
}
func (cli *ClientInfo) disconnect() {
cli.Conn.Close()
log.Printf("client %s quit.", cli.AssignId)
}
func (cli *ClientInfo) Handle() {
defer cli.Conn.Close()
cli.Conn.SetReadDeadline(time.Now().Add(1 * time.Minute))
//head buffer stream size is 8, the first 4 byte is client type and the other 4 byte is body length.
headBuf := make([]byte, 8)
for {
readHeadNum, readHeadErr := cli.Conn.Read(headBuf)
if nil != readHeadErr {
log.Printf("client %s read head error: %v.", cli.Conn.RemoteAddr().String(), readHeadErr)
break
}
if readHeadNum == cap(headBuf) {
var packLen uint32
cli.ClientType, packLen = parsePackageHead(headBuf)
bodyBuf := make([]byte, packLen)
readBodyNum, readBodyErr := cli.Conn.Read(bodyBuf)
if nil != readBodyErr {
log.Printf("client %s read body error: %v.", cli.AssignId, readBodyErr)
break
}
if readBodyNum == int(packLen) {
fmt.Printf("readBodyNum:%d,Client %s, Type is: %s, body len: %d, content: %s",
readBodyNum, cli.AssignId, cli.ClientType, packLen, string(bodyBuf))
}
}
}
}
func parsePackageHead(headBuf []byte) (string, uint32) {
headType := string(headBuf[:4])
packLen := binary.BigEndian.Uint32(headBuf[4:])
fmt.Printf("Head Buffer, clientType:%v, packLen: %v.\n", headBuf[:4], headBuf[4:])
return headType, packLen
}
func assignConnection(conn net.Conn) (bool, *ClientInfo, error) {
cli := new(ClientInfo)
cli.Conn = conn
cli.AssignId = encode.GetUUID()
cli.GmtConnect = time.Now()
cli.HostIp, cli.HostPort, _ = net.SplitHostPort(conn.LocalAddr().String())
cli.ClientIp, cli.ClientPort, _ = net.SplitHostPort(conn.RemoteAddr().String())
// poolClient[cli.AssignId] = cli
log.Printf("Client Assign ok, client info is %#v.", cli)
return true, cli, nil
}
func main() {
runtime.GOMAXPROCS(runtime.NumCPU())
log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile | log.LstdFlags)
logFile, _ := os.OpenFile("server.log", os.O_APPEND|os.O_CREATE|os.O_RDWR, 0644)
log.SetOutput(logFile)
ln, err := net.Listen("tcp", fmt.Sprintf(":%d", conf.CONFIG.Port))
if nil != err {
log.Fatalf("Start service at port %d error, %v", conf.CONFIG.Port, err)
} else {
log.Printf("Server start success at port %d.", conf.CONFIG.Port)
}
for {
conn, err := ln.Accept()
if nil != err {
log.Printf("failed accept new connection, error is %v.", err)
}
if ok, client, connErr := assignConnection(conn); ok {
go client.Handle()
} else {
log.Printf("connection assign error, %v", connErr)
}
}
}