mirror of
https://gitee.com/willfree/tcpserver-client.git
synced 2026-10-04 19:52:23 +08:00
222 lines
5.4 KiB
Go
222 lines
5.4 KiB
Go
package main
|
|
// 提供可用服务器地址的服务器
|
|
// todo: 需要对地址池操作加访问锁
|
|
|
|
import (
|
|
"TCPServerClient/utils"
|
|
"fmt"
|
|
"net"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
const (
|
|
DefaultServerIP = "localhost" // 本机服务器IP
|
|
DefaultServerPort = 50000 // 本机服务器端口号
|
|
DefaultRequestInfo = "Request Addr" // 请求可用服务器IP的命令字段
|
|
DefaultAuthenticationInfo = "User Authentication" // 验证用户身份的命令字段
|
|
DefaultSyncInfo = "Sync Addr" // 同步IP地址的命令字段
|
|
DefaultPassword = "12345678" // 消息加解密密码。必须是八位
|
|
)
|
|
|
|
type AddrServer struct {
|
|
serverIP string // 本机服务器IP
|
|
serverPort int // 本机服务器端口号
|
|
authInfo string
|
|
requestInfo string
|
|
syncInfo string
|
|
password string
|
|
addrs CanBeUsedAddrHeap // 可用服务器的地址池
|
|
nextAddrIndex int // 用于服务器地址池取用
|
|
}
|
|
|
|
// 开启server,并建立监听
|
|
func (s *AddrServer) Start() {
|
|
// 初始化Server
|
|
fmt.Println("Starting the addr server ...")
|
|
s.init()
|
|
|
|
// 创建addrs清理协程
|
|
go s.verifyIPAddrList()
|
|
|
|
// 创建 listener
|
|
listener, err := net.Listen("tcp", s.serverIP+":"+strconv.Itoa(s.serverPort))
|
|
if err != nil {
|
|
fmt.Println("Error listening", err.Error())
|
|
return
|
|
}
|
|
|
|
// 监听并接受来自客户端或服务器的连接,并进行处理
|
|
for {
|
|
conn, err := listener.Accept()
|
|
if err != nil {
|
|
fmt.Println("Error accepting", err.Error())
|
|
return
|
|
}else{
|
|
fmt.Println("AddrServer Accept conn form "+conn.RemoteAddr().String())
|
|
}
|
|
// 处理请求
|
|
go s.doAddrServerStuff(conn)
|
|
}
|
|
}
|
|
|
|
/**
|
|
初始化
|
|
*/
|
|
func (s *AddrServer) init() {
|
|
// 初始化
|
|
s.serverIP= DefaultServerIP
|
|
s.serverPort= DefaultServerPort
|
|
s.authInfo=DefaultAuthenticationInfo
|
|
s.requestInfo=DefaultRequestInfo
|
|
s.password=DefaultPassword
|
|
s.syncInfo=DefaultSyncInfo
|
|
s.nextAddrIndex=0
|
|
}
|
|
|
|
/**
|
|
处理TCP请求
|
|
*/
|
|
func (s *AddrServer) doAddrServerStuff(conn net.Conn) {
|
|
for {
|
|
// 读取原始数据
|
|
buf := make([]byte, 512)
|
|
len, err := conn.Read(buf)
|
|
if err != nil {
|
|
fmt.Println("Error reading", err.Error())
|
|
return
|
|
}
|
|
msg:=string(buf[:len])
|
|
fmt.Println("Received raw data: %v", msg)
|
|
|
|
// 解密数据为可读格式
|
|
msg=utils.DecryptMsgByDES(msg, s.password)
|
|
fmt.Println("Received decrypt data: %v", msg)
|
|
|
|
// 判断是何种请求,然后用不同的处理流程
|
|
if strings.HasPrefix(msg,s.authInfo) {
|
|
s.doRequestStuff(conn,msg)
|
|
}else if msg == s.syncInfo {
|
|
s.doSyncStuff(conn)
|
|
}else{
|
|
fmt.Println("Unable to handle request: %v", msg)
|
|
continue
|
|
}
|
|
|
|
return
|
|
}
|
|
}
|
|
|
|
/**
|
|
处理客户端请求:只对请求可用服务器地址的客户端连接进行响应
|
|
*/
|
|
func (s *AddrServer) doRequestStuff(conn net.Conn,msg string) {
|
|
// 向Server验证用户身份
|
|
// 读取用户证书
|
|
auth:=msg[len(s.authInfo):]
|
|
// 向Server发送用户证书,验证用户身份; 验证通过,向客户端返回"true"
|
|
b,err:=s.userAuthentication(auth)
|
|
if !b {
|
|
return
|
|
}else{
|
|
_ , err = conn.Write([]byte("true"))
|
|
}
|
|
|
|
// 将可用服务器地址循环返回给客户端
|
|
newAddr:=s.getCanBeUsedAddr()
|
|
_ , err = conn.Write([]byte(newAddr.ip))
|
|
if err != nil {
|
|
fmt.Println("Error writing", err.Error())
|
|
}else{
|
|
fmt.Println("Send addr information to client successfully.")
|
|
}
|
|
// 关闭本次连接
|
|
_ = conn.Close()
|
|
}
|
|
|
|
// 取出地址池中下一个地址
|
|
func (s *AddrServer) getCanBeUsedAddr() CanBeUsedAddr{
|
|
if s.addrs.Len()>s.nextAddrIndex {
|
|
s.nextAddrIndex++
|
|
return s.addrs[s.nextAddrIndex]
|
|
}else{
|
|
s.nextAddrIndex=1
|
|
return s.addrs[0]
|
|
}
|
|
}
|
|
|
|
/**
|
|
处理服务器请求:同步服务器地址
|
|
*/
|
|
func (s *AddrServer) doSyncStuff(conn net.Conn) {
|
|
// 取出conn地址
|
|
addrS := conn.RemoteAddr().String()
|
|
cb:=CanBeUsedAddr{}
|
|
cb.ip=strings.Split(addrS,":")[0]
|
|
// 检测是否已经存在该地址
|
|
index := s.addrs.IsExistAddr(cb)
|
|
if index>=0 {
|
|
// 存在,则更新时间
|
|
s.addrs[index].updateTime=time.Now()
|
|
fmt.Println("Updated addr success : "+addrS)
|
|
}else{
|
|
// 不存在,则加入
|
|
s.addrs = append(s.addrs, cb)
|
|
fmt.Println("Added addr success : "+addrS)
|
|
}
|
|
// 断开本次链接
|
|
_ = conn.Close()
|
|
}
|
|
|
|
/**
|
|
定期清理不可连接的IP地址。主动清理,每10s。
|
|
*/
|
|
func (s *AddrServer) verifyIPAddrList() {
|
|
fmt.Println("start addr timeout cleaner...")
|
|
// 当系统当前时间-T_Update>=3600s时,将该IP地址及其后的IP地址全部移除IP池
|
|
for {
|
|
for i := 0; i < len(s.addrs); i++ {
|
|
if time.Now().Sub(s.addrs[i].updateTime)>=(time.Second*3600) {
|
|
s.addrs=s.addrs[:i]
|
|
}
|
|
break
|
|
}
|
|
time.Sleep(time.Second*10)
|
|
}
|
|
}
|
|
|
|
// todo:验证用户身份
|
|
func (s *AddrServer) userAuthentication(auth string) (bool,error){
|
|
// 与min server建立连接
|
|
//...
|
|
|
|
//// 发送验证用户身份的请求给服务器
|
|
//_,err := conn.Write([]byte(utils.EncryptMsgByDES(c.authInfo,c.password)))
|
|
//if err != nil {
|
|
// fmt.Println("Error writing", err.Error())
|
|
// return false,err
|
|
//}
|
|
//
|
|
//_,err = conn.Write([]byte(utils.EncryptMsgByDES(c.user.GetCertification(),c.password)))
|
|
//if err != nil {
|
|
// fmt.Println("Error writing", err.Error())
|
|
// return false,err
|
|
//}
|
|
//
|
|
//// 接收验证结果
|
|
//buf := make([]byte, 512)
|
|
//len,err := conn.Read(buf)
|
|
//if err!=nil {
|
|
// fmt.Println("Error reading", err.Error())
|
|
// return false,err
|
|
//}
|
|
//if string(buf[:len])=="true" {
|
|
// fmt.Println("authentication success")
|
|
// return true,nil
|
|
//}else{
|
|
// return false,errors.New("authentication failed")
|
|
//}
|
|
fmt.Println("authentication success")
|
|
return true,nil
|
|
} |