Commit 2a90d4d5 by Administrator

OEM电话机硬件服务器

parents
# 默认忽略的文件
/shelf/
/workspace.xml
# 数据源本地存储已忽略文件
/dataSources/
/dataSources.local.xml
# 基于编辑器的 HTTP 客户端请求
/httpRequests/
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="Go" enabled="true" />
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/jeff_workstation_1.iml" filepath="$PROJECT_DIR$/.idea/jeff_workstation_1.iml" />
</modules>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
<mapping directory="$PROJECT_DIR$/mahonia" vcs="Git" />
</component>
</project>
\ No newline at end of file
File added
[http_server]
#debug release
ServerMode = release
ServerPort = :50000
[http_client]
#BaseUrl = http://handandev.swaylink.cn/phone/2/server/
#BaseUrl = http://dev.lezhixy.com/phone/2/server/
BaseUrl = http://127.0.0.1:1234/phone/2/server/
TimeOut = 5
[tcp_long_server]
#TCP服务监听的端口号
TcpPort = 60000
#TCP 最大连接数限制,建议设置实际设备数量的2.5倍
MaxConnections = 20000
#新建立的TCP连接,连上后多久完全没收到数据就判断为非法设备断掉,单位秒
NewConnReadDeadline = 60
#新建立的TCP连接,连上后多久没收到合法完整数据就判断为非法设备断掉,单位秒
NewConnRightfulTimeout = 120
#老连接(已验证通过确实是合法设备的tcp连接),多久没收到数据就断掉,这里设置为3倍心跳时间(若同一台设备建立了新连接,系统会立即释放老连接)
OldConnReadDeadline = 180
[log]
#debug info warn error 只允许设置这3个等级,以保证至少记录error DPanic Panci Fatal
#debug info: 记录流水数据(都存在info.log里)
#warn: 应检查原因,主要来自外部
#error DPanic Panci Fatal: 应立即检查原因来内部或硬件设备或业务服务器
Level = debug
#log文件的存储路径
Path = ./log/
#单个日志文件大小限制,单位MB
FileMaxSize = 10
#info级别日志最多保存多少份
InfoMaxFileNum = 30
#info日志最长保留天数
InfoWithMaxAge = 30
#warn级别日志最多保存多少份
WarnMaxFileNum = 30
#warn日志最长保留天数
WarnWithMaxAge = 90
#Error级别日志最多保存多少份
ErrorMaxFileNum = 10
#Error日志最长保留天数
ErrorWithMaxAge = 180
package devproduct
import "github.com/gin-gonic/gin"
func NewDCFan50(r *gin.Engine) {
var dcFan50TCP DCFan50
dcFan50TCP.NewDCFan50("DCRYM-2018-pswd.", "I can't tell YOU", 0x3E) // config
dcFan50TCP.TCPStart("60000")
dcFan50TCP.NewDCFan50API(r)
}
package devproduct
import (
"github.com/gin-gonic/gin"
"jeff_workstation_1/tcplongserver"
"net/http"
"strconv"
)
func (dev *DCFan50) NewDCFan50API(r *gin.Engine) {
router := r.Group("fan50/")
{
router.GET("online/list", dev.getOnlineList) //查整个在线设备列表
router.GET("online/total", dev.getOnlineTotal) //查在线设备总数量
router.GET("online/:devid", dev.getOnlineDevState) //查询某台设备在线状态
//router.GET("para",getDevPara) //读取某台设备某个参数
//router.POST("para",setDevPara) //设置某台设备某个参数
router.PUT("devctrl/user1/:devid", dev.devCtrlUser1Dev) //登录使用设备 //这里测试用
router.PUT("devctrl/user2/:devid", dev.devCtrlUser2Dev) //登录使用设备 //这里测试用
router.PUT("devctrl/user1stop/:devid", dev.devCtrlUser1StopDev)
router.PUT("devctrl/user2stop/:devid", dev.devCtrlUser2StopDev) //退出登录设备
router.PUT("devctrl/test/:devid", dev.devCtrlTestDev) //测试放吹风
router.PUT("devctrl/updatefirmwareversion/:devid", dev.devCtrlUpdateFirmwareVersion) //启动远程更新
router.PUT("devctrl/setipport/:devid", dev.devCtrSetIpPort) //修改TCP地址
}
}
//查整个在线设备列表
func (dev *DCFan50) getOnlineList(c *gin.Context) {
count := 0
devID := make([]uint32, 0, 5000)
dev.ConnectMap.Range(func(k, _ interface{}) bool {
if d, ok := k.(uint32); ok { // 类型断言
devID = append(devID, d) //strconv.FormatUint(uint64(d),16))
count++
} else {
dev.ConnectMap.Delete(k)
}
return true
})
//devTCP.ConnectMapRWMutex.RLock()
c.JSON(http.StatusOK, gin.H{
"status": 200,
//"data": devTCP.ConnectMap,
"data": devID,
"total": count,
"socket": dev.ConnSocketCount,
//"total": len(devTCP.ConnectMap),
"message": "OK",
})
//devTCP.ConnectMapRWMutex.RUnlock()
}
//查在线设备总数量
func (dev *DCFan50) getOnlineTotal(c *gin.Context) {
count := 0
dev.ConnectMap.Range(func(_, _ interface{}) bool {
count++
return true
})
c.JSON(http.StatusOK, gin.H{
"status": 200,
"total": count,
"socket": dev.ConnSocketCount,
// "total": len(devTCP.ConnectMap),
"message": "OK",
})
}
//查询某台设备在线状态
func (dev *DCFan50) getOnlineDevState(c *gin.Context) {
//type jsonData struct {
// ID int `json:"id"`
// Name string `json:"name"`
//}
code := 200
online := false
errMsg := "OK"
//var conn *net.TCPConn
//var ok bool
if id, err := strconv.ParseUint(c.Param("devid"), 16, 32); err == nil {
// devTCP.ConnectMapRWMutex.RLock()
// conn,ok = devTCP.ConnectMap[uint32(id)]
// devTCP.ConnectMapRWMutex.RUnlock()
if _, ok := dev.ConnectMap.Load(uint32(id)); ok {
//if ok {
online = true
}
} else {
code = 1001
errMsg = "未传入正确的设备编号格式"
}
c.JSON(http.StatusOK, gin.H{
"status": code,
"data": online,
"message": errMsg,
})
}
//////////////////////设备控制/////////////////////////////////
// 测试吹风
func (dev *DCFan50) devCtrlTestDev(c *gin.Context) {
code := 200
result := false
errMsg := "OK"
if id, err := strconv.ParseUint(c.Param("devid"), 16, 32); err == nil {
var sData tcplongserver.HexData
sData.DevID = uint32(id)
sData.CtrlCode = 0x30
if dev.TCPSend(&sData) == true {
result = true
}
} else {
code = 1001
errMsg = "未传入正确的设备编号格式"
}
c.JSON(http.StatusOK, gin.H{
"status": code,
"data": result,
"message": errMsg,
})
}
//type UserOpen struct {
// // ID int `json:"id"`
// // Name string `json:"name"`
//}
// 开启吹风
func (dev *DCFan50) devCtrlUser1Dev(c *gin.Context) {
money := 1000 //余额 单位分
price := 200 //价格 单位厘
code := 200
result := false
errMsg := "OK"
if id, err := strconv.ParseUint(c.Param("devid"), 16, 32); err == nil {
var sData tcplongserver.HexData
sData.DevID = uint32(id)
sData.CtrlCode = 0x20
sData.Data = make([]byte, 31)
sData.Data[0] = 1 //左侧
sData.Data[1] = 1 //硬件账号1
copy(sData.Data[5:], "12345678901234567890")
sData.Data[25] = byte(money)
sData.Data[26] = byte(money >> 8)
sData.Data[27] = byte(money >> 16)
sData.Data[28] = byte(money >> 24)
sData.Data[29] = byte(price)
sData.Data[30] = byte(price >> 8)
sData.Length = 31
if dev.TCPSend(&sData) == true {
result = true
}
} else {
code = 1001
errMsg = "未传入正确的设备编号格式"
}
c.JSON(http.StatusOK, gin.H{
"status": code,
"data": result,
"message": errMsg,
})
}
// 开启吹风
func (dev *DCFan50) devCtrlUser2Dev(c *gin.Context) {
money := 1000 //余额 单位分
price := 200 //价格 单位厘
code := 200
result := false
errMsg := "OK"
if id, err := strconv.ParseUint(c.Param("devid"), 16, 32); err == nil {
var sData tcplongserver.HexData
sData.DevID = uint32(id)
sData.CtrlCode = 0x20
sData.Data = make([]byte, 31)
sData.Data[0] = 2 //右侧
sData.Data[1] = 2 //硬件账号1
copy(sData.Data[5:], "12345678901234567890")
sData.Data[25] = byte(money)
sData.Data[26] = byte(money >> 8)
sData.Data[27] = byte(money >> 16)
sData.Data[28] = byte(money >> 24)
sData.Data[29] = byte(price)
sData.Data[30] = byte(price >> 8)
sData.Length = 31
if dev.TCPSend(&sData) == true {
result = true
}
} else {
code = 1001
errMsg = "未传入正确的设备编号格式"
}
c.JSON(http.StatusOK, gin.H{
"status": code,
"data": result,
"message": errMsg,
})
}
func (dev *DCFan50) devCtrlUser1StopDev(c *gin.Context) {
code := 200
result := false
errMsg := "OK"
if id, err := strconv.ParseUint(c.Param("devid"), 16, 32); err == nil {
var sData tcplongserver.HexData
sData.DevID = uint32(id)
sData.Data = make([]byte, 5)
sData.Data[0] = 1
sData.Data[1] = 1
sData.Length = 5
sData.CtrlCode = 0x21
if dev.TCPSend(&sData) == true {
result = true
}
} else {
code = 1001
errMsg = "未传入正确的设备编号格式"
}
c.JSON(http.StatusOK, gin.H{
"status": code,
"data": result,
"message": errMsg,
})
}
func (dev *DCFan50) devCtrlUser2StopDev(c *gin.Context) {
code := 200
result := false
errMsg := "OK"
if id, err := strconv.ParseUint(c.Param("devid"), 16, 32); err == nil {
var sData tcplongserver.HexData
sData.DevID = uint32(id)
sData.Data = make([]byte, 5)
sData.Data[0] = 2
sData.Data[1] = 2
sData.Length = 5
sData.CtrlCode = 0x21
if dev.TCPSend(&sData) == true {
result = true
}
} else {
code = 1001
errMsg = "未传入正确的设备编号格式"
}
c.JSON(http.StatusOK, gin.H{
"status": code,
"data": result,
"message": errMsg,
})
}
func (dev *DCFan50) devCtrlUpdateFirmwareVersion(c *gin.Context) {
code := 200
result := false
errMsg := "OK"
if id, err := strconv.ParseUint(c.Param("devid"), 16, 32); err == nil {
type paraOneString struct {
DevTime uint32 `json:"dev_send_time"`
DevID []uint32 `json:"devId"`
Value string `json:"value"`
}
var data paraOneString
c.ShouldBindJSON(&data)
var sData tcplongserver.HexData
sData.DevID = uint32(id)
sData.Data = make([]byte, len(data.Value)+1)
copy(sData.Data, data.Value)
sData.Length = byte(len(sData.Data))
sData.CtrlCode = 0x71
if dev.TCPSend(&sData) == true {
result = true
}
} else {
code = 1001
errMsg = "未传入正确的设备编号格式"
}
c.JSON(http.StatusOK, gin.H{
"status": code,
"data": result,
"message": errMsg,
})
}
func (dev *DCFan50) devCtrSetIpPort(c *gin.Context) {
code := 200
result := false
errMsg := "OK"
if id, err := strconv.ParseUint(c.Param("devid"), 16, 32); err == nil {
type paraOneString struct {
DevTime uint32 `json:"dev_send_time"`
DevID []uint32 `json:"devId"`
Value string `json:"value"`
}
var data paraOneString
c.ShouldBindJSON(&data)
var sData tcplongserver.HexData
sData.DevID = uint32(id)
sData.Data = []byte(data.Value)
sData.Length = byte(len(data.Value))
sData.CtrlCode = 0x03
if dev.TCPSend(&sData) == true {
result = true
}
} else {
code = 1001
errMsg = "未传入正确的设备编号格式"
}
c.JSON(http.StatusOK, gin.H{
"status": code,
"data": result,
"message": errMsg,
})
}
package devproduct
import (
"fmt"
"jeff_workstation_1/tcplongserver"
)
//type IDCFan50 interface {
// Response(conn *net.TCPConn,data []byte,len int) bool
//}
type DCFan50 struct {
tcplongserver.DCLongTCPHex
}
func (dev *DCFan50) NewDCFan50(password string, iv string, devType uint8) {
dev.InitNewDCLongTCPHex(password, iv, devType, dev.response)
}
//TCP收到的协议解析
func (dev *DCFan50) response(data *tcplongserver.HexData) { //(result devproduct.HexData){
ctrlCode := data.CtrlCode
data.CtrlCode = 0
switch ctrlCode {
case 0x80: //读ID,莫得卵用
case 0x86: //硬件响应修改密钥,莫得卵用
case 0x83: //TCP服务器地址
case 0x84: //心跳参数
fmt.Println("心跳参数: ")
case 0x41: //状态心跳
if data.Length == 15 || data.Length == 35 || data.Length == 55 {
fmt.Printf("状态心跳:%x\n", data.Data[1])
fmt.Printf("通信延迟:%d\n", data.Data[0])
fmt.Printf("左电流:%dmA , 右电流:%dmA\n", uint16(data.Data[3])<<8+uint16(data.Data[2]), uint16(data.Data[5])<<8+uint16(data.Data[4]))
fmt.Printf("左电阻:%d , 右电阻:%d\n", uint16(data.Data[7])<<8+uint16(data.Data[6]), uint16(data.Data[9])<<8+uint16(data.Data[8]))
fmt.Printf("左温度:%d℃ , 右温度:%d℃\n", data.Data[10], data.Data[11])
fmt.Printf("VCC-L:%d , VCC-H:%d\n", data.Data[12], data.Data[13])
fmt.Printf("在用账单: %d", data.Data[14])
if data.Length > 15 {
fmt.Printf("-%s", string(data.Data[15:35]))
}
if data.Length > 35 {
fmt.Printf("-%s", string(data.Data[35:55]))
}
fmt.Println("\n----------------------------------------------------")
} else {
// logger 内容错误
}
data.CtrlCode = ctrlCode | 0x80
data.Length = 0
case 0x7e: //异常
if data.Length == 15 || data.Length == 35 || data.Length == 55 {
fmt.Printf("状态异常:%x\n", data.Data[1])
fmt.Printf("通信延迟:%d\n", data.Data[0])
fmt.Printf("左电流:%dmA , 右电流:%dmA\n", uint16(data.Data[3])<<8+uint16(data.Data[2]), uint16(data.Data[5])<<8+uint16(data.Data[4]))
fmt.Printf("左电阻:%d , 右电阻:%d\n", uint16(data.Data[7])<<8+uint16(data.Data[6]), uint16(data.Data[9])<<8+uint16(data.Data[8]))
fmt.Printf("左温度:%d℃ , 右温度:%d℃\n", data.Data[10], data.Data[11])
fmt.Printf("VCC-L:%d , VCC-H:%d\n", data.Data[12], data.Data[13])
fmt.Printf("在用账单: %d", data.Data[14])
if data.Length > 15 {
fmt.Printf("-%s", string(data.Data[15:35]))
}
if data.Length > 35 {
fmt.Printf("-%s", string(data.Data[35:55]))
}
fmt.Println("\n----------------------------------------------------")
} else {
// logger 内容错误
}
data.CtrlCode = ctrlCode | 0x80
data.Length = 0
case 0x22: // 上报正常账单
if data.Length == 37 {
fmt.Println("收到正常账单:")
fmt.Printf("账单号:%s,消费金额:%d分,使用时长:%dX0.1秒,占用时长:%dX0.1秒,最大电流:%dmA,接触电阻:%d豪欧,温度:%d摄氏度,开关次数:%d,退出原因:%d\n",
data.Data[:20],
int(data.Data[20])+(int(data.Data[21])<<8),
int(data.Data[22])+(int(data.Data[23])<<8)+(int(data.Data[24])<<16)+(int(data.Data[25])<<24),
int(data.Data[26])+(int(data.Data[27])<<8)+(int(data.Data[28])<<16)+(int(data.Data[29])<<24),
int(data.Data[30])+(int(data.Data[31])<<8),
int(data.Data[32])+(int(data.Data[33])<<8),
data.Data[34],
data.Data[35],
data.Data[36])
}
data.CtrlCode = ctrlCode | 0x80
case 0xB0: // 响应进入测试吹风
fmt.Println("硬件响应进入测试吹风模式")
default:
// logger 未知信息
fmt.Printf("协议未收录的控制字:0x%x\n", ctrlCode)
}
//return
}
package devproduct
import (
"github.com/gin-gonic/gin"
"jeff_workstation_1/jeffutil"
)
func NewDCPhone10(r *gin.Engine) {
var dcPhone10TCP DCPhone10
dcPhone10TCP.NewDCPhone10("DCRYM-2018-pswd.", "I can't tell YOU", 0x5A) // config
dcPhone10TCP.TCPStart(jeffutil.TcpLongPort)
dcPhone10TCP.NewDCPhone10API(r)
}
package devproduct
import (
"github.com/gin-gonic/gin"
"go.uber.org/zap"
"jeff_workstation_1/logger"
"jeff_workstation_1/tcplongserver"
"net"
"net/http"
"strconv"
)
func (dev *DCPhone10) NewDCPhone10API(r *gin.Engine) {
router := r.Group("phone10/")
{
router.GET("online/all", dev.getOnlineAll) //查询所有在线设备列表
router.GET("online/list", dev.getOnlineList) //查设备是否在线
router.GET("online/num", dev.getOnlineTotal) //查在线设备总数量
router.DELETE("online/", dev.putOnlineClose) //批量强制关闭设备连接
router.GET("para/:paraName", dev.getDevPara) //读取某些设备某个参数
router.POST("para/:paraName", dev.setDevPara) //设置某些设备某个参数
router.PUT("ctrl/:paraName", dev.setDevPara) //批量重启设备 restart_device
router.GET("ctrl/:paraName", dev.getDevPara) // 读取固件版本号 read_firmware_version
//router.PUT("ctrl/:paraName",dev.setDevPara) //固件更新 update_firmware //远程拨号 online_dial
router.POST("ctrl/:paraName", dev.setDevPara) //远程拨号 online_dial //固件更新 update_firmware
}
}
//查设备是否在线
func (dev *DCPhone10) getOnlineList(c *gin.Context) {
type st struct {
DevID []uint32 `json:"devId"`
}
var dataIn st
if err := c.ShouldBindJSON(&dataIn); err != nil {
logger.Log.Error("c.ShouldBindJSON(&dataIn)",
zap.String("Src", "getOnlineList"),
zap.Error(err))
}
type DataO struct {
Count int `json:"count"`
DevID map[uint32]bool `json:"devId"`
}
var dataOut DataO
dataOut.DevID = make(map[uint32]bool)
for _, id := range dataIn.DevID {
if _, ok := dev.ConnectMap.Load(id); ok {
dataOut.DevID[id] = true
dataOut.Count++
} else {
dataOut.DevID[id] = false
}
}
c.JSON(http.StatusOK, gin.H{
"status": 200,
"data": dataOut,
"message": "OK",
})
}
//查在线设备总数量
func (dev *DCPhone10) getOnlineTotal(c *gin.Context) {
type DataO struct {
Count int `json:"count"`
Socket int `json:"socket"`
}
var dataOut DataO
dev.ConnectMap.Range(func(_, _ interface{}) bool {
dataOut.Count++
return true
})
dataOut.Socket = dev.ConnSocketCount
c.JSON(http.StatusOK, gin.H{
"status": 200,
"data": dataOut,
"message": "OK",
})
}
//查整个在线设备列表
func (dev *DCPhone10) getOnlineAll(c *gin.Context) {
type DataO struct {
Count int `json:"count"`
DevID []uint32 `json:"devId"`
Socket int `json:"socket"`
}
var dataOut DataO
//dataOut.DevID = make([]uint32,0,5000)
dev.ConnectMap.Range(func(k, _ interface{}) bool {
if d, ok := k.(uint32); ok { // 类型断言
dataOut.DevID = append(dataOut.DevID, d) //strconv.FormatUint(uint64(d),16))
dataOut.Count++
} else {
dev.ConnectMap.Delete(k)
}
return true
})
dataOut.Socket = dev.ConnSocketCount
c.JSON(http.StatusOK, gin.H{
"status": 200,
"data": dataOut,
"message": "OK",
})
}
// 主动关闭设备链接
func (dev *DCPhone10) putOnlineClose(c *gin.Context) {
type st struct {
DevID []uint32 `json:"devId"`
}
var data st
if err := c.ShouldBindJSON(&data); err != nil {
logger.Log.Error("c.ShouldBindJSON(&data)",
zap.String("Src", "putOnlineClose"),
zap.Error(err))
}
type DataO struct {
Count int `json:"count"`
DevID map[uint32]bool `json:"devId"`
}
var dataOut DataO
dataOut.DevID = make(map[uint32]bool)
for _, id := range data.DevID {
if conn, ok := dev.ConnectMap.Load(id); ok {
if c, ok := conn.(*net.TCPConn); ok { // 类型断言
_ = c.Close()
} /*else { // 类型断言失败
}*/
dev.ConnectMap.Delete(id)
dataOut.Count++
dataOut.DevID[id] = true
} else {
dataOut.DevID[id] = false
}
}
c.JSON(http.StatusOK, gin.H{
"status": 200,
"data": dataOut,
"message": "OK",
})
}
// 以下为参数处理-----------------------------------------------------------------------------------------
//读取硬件设备参数
func (dev *DCPhone10) getDevPara(c *gin.Context) {
para := c.Param("paraName")
type st struct {
DevID []uint32 `json:"devId"`
}
var data st
if err := c.ShouldBindJSON(&data); err != nil {
logger.Log.Error("c.ShouldBindJSON(&data)",
zap.String("Src", "getDevPara"),
zap.Error(err))
}
type DataO struct {
Count int `json:"count"`
DevID map[uint32]bool `json:"devId"`
}
var dataOut DataO
dataOut.DevID = make(map[uint32]bool)
returnState := 200
returnMsg := "OK"
if value, ok := httpParaNameMapString2Hex[para]; ok {
var sData tcplongserver.HexData
sData.CtrlCode = value
sData.Length = 0
for _, id := range data.DevID {
sData.DevID = id
if dev.TCPSend(&sData) == true {
dataOut.DevID[id] = true
} else {
dataOut.DevID[id] = false
}
}
} else {
returnState = 2001 //
returnMsg = para + ":参数未定义"
}
c.JSON(http.StatusOK, gin.H{
"status": returnState,
"data": dataOut,
"message": returnMsg,
})
}
// 设置硬件设备参数
func (dev *DCPhone10) setDevPara(c *gin.Context) {
returnState := 200
returnMsg := "OK"
type DataO struct {
Count int `json:"count"`
DevID map[uint32]bool `json:"devId"`
}
var dataOut DataO
dataOut.DevID = make(map[uint32]bool)
var sDevId []uint32
var sTcpData tcplongserver.HexData
sTcpData.Data = make([]byte, 255)
para := c.Param("paraName")
sTcpData.CtrlCode = httpParaNameMapString2Hex[para]
switch para {
case "tcp_server_addr":
var data paraTcpServerAddr
if err := c.ShouldBindJSON(&data); err != nil {
logger.Log.Error("c.ShouldBindJSON(&data)",
zap.String("Src", "case \"tcp_server_addr\""),
zap.Error(err))
}
sTcpData.Data = []byte("\"" + data.Value.IP + "\"," + strconv.Itoa(int(data.Value.Port)))
sTcpData.Length = byte(len(sTcpData.Data))
sDevId = data.DevID
case "select_sim_module":
var data paraSelectSimModule
if err := c.ShouldBindJSON(&data); err != nil {
logger.Log.Error("c.ShouldBindJSON(&data)",
zap.String("Src", "case \"select_sim_module\""),
zap.Error(err))
}
sTcpData.Data[0] = data.Value.Net<<1 | data.Value.Call
sTcpData.Length = 1
sDevId = data.DevID
case "heart":
var data paraHeart
if err := c.ShouldBindJSON(&data); err != nil {
logger.Log.Error("c.ShouldBindJSON(&data)",
zap.String("Src", "case \"heart\""),
zap.Error(err))
}
sTcpData.Data[0] = byte(data.Value.Time)
sTcpData.Data[1] = byte(data.Value.Time >> 8)
sTcpData.Data[2] = data.Value.VoidCount
sTcpData.Length = 3
sDevId = data.DevID
case "beep_volume", "speech_volume", "speech_speed": //这些都是1个byte的参数
var data paraOneByte
if err := c.ShouldBindJSON(&data); err != nil {
logger.Log.Error("c.ShouldBindJSON(&data)",
zap.String("Src", "case \"beep_volume\",\"speech_volume\",\"speech_speed\""),
zap.Error(err))
}
sTcpData.Data[0] = data.Value
sTcpData.Length = 1
sDevId = data.DevID
case "key_password", "online_dial", "update_firmware", "restart_device": //
var data paraOneString
if err := c.ShouldBindJSON(&data); err != nil {
logger.Log.Error("c.ShouldBindJSON(&data)",
zap.String("Src", "case \"key_password\",\"online_dial\",\"update_firmware\",\"restart_device\""),
zap.Error(err))
}
sTcpData.Data = []byte(data.Value)
sTcpData.Length = byte(len(data.Value))
sDevId = data.DevID
case "work_time": // 工作时段
var data paraWorkTime
if err := c.ShouldBindJSON(&data); err != nil {
logger.Log.Error("c.ShouldBindJSON(&data)",
zap.String("Src", "case \"work_time\""),
zap.Error(err))
}
i := 0
for ; i < len(data.Value); i++ {
sTcpData.Data[0+i*6] = byte(data.Value[i].Start)
sTcpData.Data[1+i*6] = byte(data.Value[i].Start >> 8)
sTcpData.Data[2+i*6] = byte(data.Value[i].Stop)
sTcpData.Data[3+i*6] = byte(data.Value[i].Stop >> 8)
if data.Value[i].EnableCall {
sTcpData.Data[4+i*6] |= 1
} // 允许刷卡
if data.Value[i].CallIn {
sTcpData.Data[4+i*6] |= 1 << 1
} // 允许呼入
if data.Value[i].EnableKeyboard {
sTcpData.Data[4+i*6] |= 1 << 2
} // 允许键盘拨号
if data.Value[i].EnableMsg {
sTcpData.Data[4+i*6] |= 1 << 3
} // 允许留言
if data.Value[i].EnableSos {
sTcpData.Data[4+i*6] |= 1 << 4
} // 允许紧急呼叫
if len(data.Value[i].WeekDay) == 7 {
for j := 0; j < 7; j++ {
if data.Value[i].WeekDay[j] {
sTcpData.Data[5+i*6] |= 1 << j
}
}
} else {
returnState = 2801 //
returnMsg = para + ":week_day字段长度必须为7"
i = 0
break
}
}
sTcpData.Length = byte(i * 6)
sDevId = data.DevID
default:
returnState = 2001 //
returnMsg = para + ":参数未定义"
}
for _, id := range sDevId {
sTcpData.DevID = id
if dev.TCPSend(&sTcpData) == true {
dataOut.DevID[id] = true
} else {
dataOut.DevID[id] = false
}
}
c.JSON(http.StatusOK, gin.H{
"status": returnState,
"data": dataOut,
"message": returnMsg,
})
}
package devproduct
// const baseSwayUrl = "https://v3.biyingniao.com" // 配置文件
var httpParaNameMapString2Hex = map[string]byte{
// ***设备参数类***
"tcp_server_addr": 0x03, // 硬件连接tcp服务器地址端口
"heart": 0x04, // 心跳间隔次数 和 心跳间隔时间
"beep_volume": 0x05, // 蜂鸣器音量 0-100
"speech_volume": 0x06, // 通话音量 0-10
"speech_speed": 0x07, // 语速 0-9
"select_sim_module": 0x08, // 拨号卡选择
"work_time": 0x09, //工作时段
"key_password": 0x0a, // 最长10个字符(数字加*#)
// ***设备控制类***
"restart_device": 0x32, // 重启设备
"read_firmware_version": 0x70, // 读取固件版本
"update_firmware": 0x71, // 启动远程更新
"online_dial": 0x30, // 远程拨号
}
var httpParaNameMapHex2String = map[byte]string{
// ***设备参数类***
0x03 | 0x80: "para/tcp_server_addr", // 硬件连接tcp服务器地址端口
0x04 | 0x80: "para/heart", // 心跳间隔次数 和 心跳间隔时间
0x05 | 0x80: "para/beep_volume", // 蜂鸣器音量 0-100
0x06 | 0x80: "para/speech_volume", // 通话音量 0-10
0x07 | 0x80: "para/speech_speed", // 语速 0-9
0x08 | 0x80: "para/select_sim_module", // 拨号卡选择
0x09 | 0x80: "para/work_time", //工作时段
0x0a | 0x80: "para/key_password", // 最长10个字符(数字加*#)
// ***设备状态及控制类***
0x32 | 0x80: "ctrl/restart_device", // 重启设备 上下行均空
0x70 | 0x80: "ctrl/read_firmware_version", // 读取固件版本
0x71 | 0x80: "ctrl/update_firmware", // 启动远程更新
0x30 | 0x80: "ctrl/online_dial", // 远程拨号
0x3f: "ctrl/dev_restart_login", // 开机注册
0x41: "ctrl/dev_up_status", // 心跳上报状态
// ***设备使用类***
0x20: "usedevice/dev_get_family_num", // 查询亲情号码
0x23: "usedevice/dev_get_family_msg", // 查询留言
0x24: "usedevice/dev_read_family_msg", //上报已读留言
0x21: "usedevice/dev_get_call_time", // 获取自由拨号允许时长
0x22: "usedevice/dev_post_call_log", // 上报通话记录
}
// 以下其实可以封装成一个,然后value用interface, 但是可能是反射吧,这样用效率可能高些
type devUpRestartLogin struct {
DevTime uint32 `json:"dev_send_time"`
DevID []uint32 `json:"devId"`
Value struct {
ResetReason byte `json:"reset_reason"`
Imei0 string `json:"imei_0"`
Iccid0 string `json:"iccid_0"`
Imei1 string `json:"imei_1"`
Iccid1 string `json:"iccid_1"`
Longitude string `json:"longitude"`
Latitude string `json:"latitude"`
FirmwareVersion string `json:"firmware_version"`
} `json:"value"`
}
type devUpFirmwareInfo struct {
DevTime uint32 `json:"dev_send_time"`
DevID []uint32 `json:"devId"`
Value struct {
MD5 []byte `json:"md5"`
Length uint32 `json:"length"`
Version string `json:"version"`
} `json:"value"`
}
type devUpRespondUpdateFirmware struct {
DevTime uint32 `json:"dev_send_time"`
DevID []uint32 `json:"devId"`
Value struct {
RespondUpdateFirmware bool `json:"respond_update_firmware"`
Version string `json:"version"`
MD5 []byte `json:"md5"` // 只有 espondUpdateFirmware == false 才有
Length uint32 `json:"length"` // 只有 RespondUpdateFirmware == false 才有
} `json:"value"`
}
type paraTcpServerAddr struct {
DevTime uint32 `json:"dev_send_time"`
DevID []uint32 `json:"devId"`
Value struct {
IP string `json:"ip"`
Port uint16 `json:"port"`
} `json:"value"`
}
type paraSelectSimModule struct {
DevTime uint32 `json:"dev_send_time"`
DevID []uint32 `json:"devId"`
Value struct {
Net byte `json:"net"` // 0/1
Call byte `json:"call"` // 0/1
} `json:"value"`
}
type paraHeart struct {
DevTime uint32 `json:"dev_send_time"`
DevID []uint32 `json:"devId"`
Value struct {
Time uint16 `json:"time"` // 推荐60
VoidCount byte `json:"void_count"` // 推荐10
} `json:"value"`
}
type paraNoValue struct {
DevTime uint32 `json:"dev_send_time"`
DevID []uint32 `json:"devId"`
}
type paraOneByte struct {
DevTime uint32 `json:"dev_send_time"`
DevID []uint32 `json:"devId"`
Value byte `json:"value"`
}
type paraOneString struct {
DevTime uint32 `json:"dev_send_time"`
DevID []uint32 `json:"devId"`
Value string `json:"value"`
}
type paraWorkTime struct {
DevTime uint32 `json:"dev_send_time"`
DevID []uint32 `json:"devId"`
Value []struct {
Start uint16 `json:"start"`
Stop uint16 `json:"stop"`
EnableKeyboard bool `json:"enable_keyboard"`
CallIn bool `json:"call_in"`
EnableSos bool `json:"enable_sos"`
EnableCall bool `json:"enable_call"`
EnableMsg bool `json:"enable_msg"`
WeekDay []bool `json:"week_day"`
} `json:"value"`
}
File added
module jeff_workstation_1
go 1.16
require (
github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394 // indirect
github.com/gin-gonic/gin v1.7.2 // indirect
github.com/go-playground/validator/v10 v10.7.0 // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/json-iterator/go v1.1.11 // indirect
github.com/leodido/go-urn v1.2.1 // indirect
github.com/lestrrat-go/strftime v1.0.5 // indirect
github.com/mattn/go-colorable v0.1.8 // indirect
github.com/mattn/go-isatty v0.0.13 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.1 // indirect
github.com/natefinch/lumberjack v2.0.0+incompatible // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/ugorji/go v1.2.6 // indirect
go.uber.org/atomic v1.9.0 // indirect
go.uber.org/multierr v1.7.0 // indirect
go.uber.org/zap v1.18.1 // indirect
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 // indirect
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c // indirect
golang.org/x/text v0.3.6 // indirect
google.golang.org/protobuf v1.27.1 // indirect
gopkg.in/ini.v1 v1.62.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
)
This diff is collapsed. Click to expand it.
package jeffhttprequest
import (
"bytes"
"go.uber.org/zap"
"io/ioutil"
"jeff_workstation_1/jeffutil"
"jeff_workstation_1/logger"
"net/http"
"time"
)
// Post 发送POST请求
func Post(url string, jsonStr []byte) ([]byte, error) { //直接传BYTE,因为我不知道interface是不是反射,可能影响性能
//jsonStr, _ := json.Marshal(data)
req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonStr))
if err != nil {
logger.Log.Error("req.Header.Add(\"content-type\", \"application/json\")",
zap.String("Src", "HTTP-CLIENT-POST"),
zap.String("Url", url),
zap.Error(err),
zap.ByteString("Req", jsonStr))
return nil, err
}
defer req.Body.Close()
req.Header.Add("content-type", "application/json")
client := &http.Client{Timeout: jeffutil.HttpClientTimeOut}
startTime := time.Now().UnixNano() // time.Now()
resp, err2 := client.Do(req)
spendTime := time.Now().UnixNano() - startTime // spendTime := fmt.Sprintf("%d ms", (time.Since(startTime).Nanoseconds()+500000)/1000000.0)
if err2 != nil {
logger.Log.Error("client.Do(req)",
zap.String("Src", "HTTP-CLIENT-POST"),
zap.String("Url", url),
zap.Int64("SpendNanoS", spendTime),
zap.Error(err2),
zap.ByteString("Req", jsonStr))
return nil, err2
}
defer resp.Body.Close()
// client.CloseIdleConnections()
result, _ := ioutil.ReadAll(resp.Body)
// result, _ := ioutil.ReadAll(transform.NewReader(resp.Body, simplifiedchinese.GBK.NewEncoder()))
//enc := mahonia.NewEncoder("gbk")
//ret := enc.ConvertString(string(result))
//test,_ := ioutil.ReadAll(transform.NewReader(bytes.NewReader([]byte(ret)), simplifiedchinese.GBK.NewEncoder()))
logger.Log.Info(string(result),
zap.String("Src", "HTTP-CLIENT-POST"),
zap.Int64("SpendNanoS", spendTime),
zap.String("Url", url),
zap.ByteString("Req", jsonStr))
//return []byte(ret),nil
return result, nil
}
//发送GET请求
//func Get(url string, jsonStr []byte) ([]byte, error) {
// client := http.Client{Timeout: jeffutil.HttpClientTimeOut}
// startTime := time.Now().UnixNano()// time.Now()
// resp, error := client.Get(url)
// spendTime := time.Now().UnixNano() - startTime
// if error != nil {
// log.WithFields(log.Fields{
// "Src": "HTTP-CLIENT-GET",
// "Url": url,
// "Err": error,
// }).Errorln("client.Get(url)")
// return nil,error
// }
// defer resp.Body.Close()
//
// var buffer [512]byte
// result := bytes.NewBuffer(nil)
// for {
// n, err := resp.Body.Read(buffer[0:])
// result.Write(buffer[0:n])
// if err != nil{
// if err == io.EOF {
// break
// } else {
// log.WithFields(log.Fields{
// "Src": "HTTP-CLIENT-GET",
// "Url": url,
// "Err": err,
// "RespStatus": resp.Status,
// }).Errorln("resp.Body.Read(buffer[0:])")
// return nil,err
// }
// }
// }
//
// resultString := result.Bytes()
//
// // httpClientLogger.Infoln("[GET]",spendTime,"mS-",url,"-",resultString)
// log.WithFields(log.Fields{
// "Src": "HTTP-CLIENT-GET",
// "SpendNanoS":spendTime,
// "Url": url,
// "RespStatus": resp.Status,
// }).Infoln(resultString)
//
// return resultString,nil
//}
File added
package jeffutil
// 全角转换半角
func DBCtoSBC(s string) string {
retstr := ""
for _, i := range s {
inside_code := i
if inside_code == 12288 {
inside_code = 32
} else {
inside_code -= 65248
}
if inside_code < 32 || inside_code > 126 {
retstr += string(i)
} else {
retstr += string(inside_code)
}
}
return retstr
}
//import (
// "sort"
// "strings"
//)
//
//type dict struct {
// x, y rune
//}
//
//var toSBC = []dict{
// {0x00A2, 0xFFE0},
// {0x00A3, 0xFFE1},
// {0x00A5, 0xFFE5},
// {0x00A6, 0xFFE4},
// {0x00AC, 0xFFE2},
// {0x00AF, 0xFFE3},
// {0xFF61, 0x3002},
// {0xFF62, 0x300C},
// {0xFF63, 0x300D},
// {0xFF64, 0x3001},
// {0xFF65, 0x30FB},
// {0xFF66, 0x30F2},
// {0xFF67, 0x30A1},
// {0xFF68, 0x30A3},
// {0xFF69, 0x30A5},
// {0xFF6A, 0x30A7},
// {0xFF6B, 0x30A9},
// {0xFF6C, 0x30E3},
// {0xFF6D, 0x30E5},
// {0xFF6E, 0x30E7},
// {0xFF6F, 0x30C3},
// {0xFF70, 0x30FC},
// {0xFF71, 0x30A2},
// {0xFF72, 0x30A4},
// {0xFF73, 0x30A6},
// {0xFF74, 0x30A8},
// {0xFF75, 0x30AA},
// {0xFF76, 0x30AB},
// {0xFF77, 0x30AD},
// {0xFF78, 0x30AF},
// {0xFF79, 0x30B1},
// {0xFF7A, 0x30B3},
// {0xFF7B, 0x30B5},
// {0xFF7C, 0x30B7},
// {0xFF7D, 0x30B9},
// {0xFF7E, 0x30BB},
// {0xFF7F, 0x30BD},
// {0xFF80, 0x30BF},
// {0xFF81, 0x30C1},
// {0xFF82, 0x30C4},
// {0xFF83, 0x30C6},
// {0xFF84, 0x30C8},
// {0xFF85, 0x30CA},
// {0xFF86, 0x30CB},
// {0xFF87, 0x30CC},
// {0xFF88, 0x30CD},
// {0xFF89, 0x30CE},
// {0xFF8A, 0x30CF},
// {0xFF8B, 0x30D2},
// {0xFF8C, 0x30D5},
// {0xFF8D, 0x30D8},
// {0xFF8E, 0x30DB},
// {0xFF8F, 0x30DE},
// {0xFF90, 0x30DF},
// {0xFF91, 0x30E0},
// {0xFF92, 0x30E1},
// {0xFF93, 0x30E2},
// {0xFF94, 0x30E4},
// {0xFF95, 0x30E6},
// {0xFF96, 0x30E8},
// {0xFF97, 0x30E9},
// {0xFF98, 0x30EA},
// {0xFF99, 0x30EB},
// {0xFF9A, 0x30EC},
// {0xFF9B, 0x30ED},
// {0xFF9C, 0x30EF},
// {0xFF9D, 0x30F3},
// {0xFF9E, 0x309B},
// {0xFF9F, 0x309C},
// {0xFFA0, 0x3164},
// {0xFFC2, 0x314F},
// {0xFFC3, 0x3150},
// {0xFFC4, 0x3151},
// {0xFFC5, 0x3152},
// {0xFFC6, 0x3153},
// {0xFFC7, 0x3154},
// {0xFFCA, 0x3155},
// {0xFFCB, 0x3156},
// {0xFFCC, 0x3157},
// {0xFFCD, 0x3158},
// {0xFFCE, 0x3159},
// {0xFFCF, 0x315A},
// {0xFFD2, 0x315B},
// {0xFFD3, 0x315C},
// {0xFFD4, 0x315D},
// {0xFFD5, 0x315E},
// {0xFFD6, 0x315F},
// {0xFFD7, 0x3160},
// {0xFFDA, 0x3161},
// {0xFFDB, 0x3162},
// {0xFFDC, 0x3163},
// {0xFFE8, 0x2502},
// {0xFFE9, 0x2190},
// {0xFFEA, 0x2191},
// {0xFFEB, 0x2192},
// {0xFFEC, 0x2193},
// {0xFFED, 0x25A0},
// {0xFFEE, 0x25CB},
//}
//
//var toDBC = []dict{
// {0x2190, 0xFFE9},
// {0x2191, 0xFFEA},
// {0x2192, 0xFFEB},
// {0x2193, 0xFFEC},
// {0x3000, 0x0020},
// {0x3001, 0xFF64},
// {0x3002, 0xFF61},
// {0x300C, 0xFF62},
// {0x300D, 0xFF63},
// {0x309B, 0xFF9E},
// {0x309C, 0xFF9F},
// {0x30A1, 0xFF67},
// {0x30A2, 0xFF71},
// {0x30A3, 0xFF68},
// {0x30A4, 0xFF72},
// {0x30A5, 0xFF69},
// {0x30A6, 0xFF73},
// {0x30A7, 0xFF6A},
// {0x30A8, 0xFF74},
// {0x30A9, 0xFF6B},
// {0x30AA, 0xFF75},
// {0x30AB, 0xFF76},
// {0x30AD, 0xFF77},
// {0x30AF, 0xFF78},
// {0x30B1, 0xFF79},
// {0x30B3, 0xFF7A},
// {0x30B5, 0xFF7B},
// {0x30B7, 0xFF7C},
// {0x30B9, 0xFF7D},
// {0x30BB, 0xFF7E},
// {0x30BD, 0xFF7F},
// {0x30BF, 0xFF80},
// {0x30C1, 0xFF81},
// {0x30C3, 0xFF6F},
// {0x30C4, 0xFF82},
// {0x30C6, 0xFF83},
// {0x30C8, 0xFF84},
// {0x30CA, 0xFF85},
// {0x30CB, 0xFF86},
// {0x30CC, 0xFF87},
// {0x30CD, 0xFF88},
// {0x30CE, 0xFF89},
// {0x30CF, 0xFF8A},
// {0x30D2, 0xFF8B},
// {0x30D5, 0xFF8C},
// {0x30D8, 0xFF8D},
// {0x30DB, 0xFF8E},
// {0x30DE, 0xFF8F},
// {0x30DF, 0xFF90},
// {0x30E0, 0xFF91},
// {0x30E1, 0xFF92},
// {0x30E2, 0xFF93},
// {0x30E3, 0xFF6C},
// {0x30E4, 0xFF94},
// {0x30E5, 0xFF6D},
// {0x30E6, 0xFF95},
// {0x30E7, 0xFF6E},
// {0x30E8, 0xFF96},
// {0x30E9, 0xFF97},
// {0x30EA, 0xFF98},
// {0x30EB, 0xFF99},
// {0x30EC, 0xFF9A},
// {0x30ED, 0xFF9B},
// {0x30EF, 0xFF9C},
// {0x30F2, 0xFF66},
// {0x30F3, 0xFF9D},
// {0x30FB, 0xFF65},
// {0x30FC, 0xFF70},
// {0x314F, 0xFFC2},
// {0x3150, 0xFFC3},
// {0x3151, 0xFFC4},
// {0x3152, 0xFFC5},
// {0x3153, 0xFFC6},
// {0x3154, 0xFFC7},
// {0x3155, 0xFFCA},
// {0x3156, 0xFFCB},
// {0x3157, 0xFFCC},
// {0x3158, 0xFFCD},
// {0x3159, 0xFFCE},
// {0x315A, 0xFFCF},
// {0x315B, 0xFFD2},
// {0x315C, 0xFFD3},
// {0x315D, 0xFFD4},
// {0x315E, 0xFFD5},
// {0x315F, 0xFFD6},
// {0x3160, 0xFFD7},
// {0x3161, 0xFFDA},
// {0x3162, 0xFFDB},
// {0x3163, 0xFFDC},
// {0x3164, 0xFFA0},
// {0xFF5F, 0x2985},
// {0xFF60, 0x2986},
// {0xFFE0, 0x00A2},
// {0xFFE1, 0x00A3},
// {0xFFE2, 0x00AC},
// {0xFFE3, 0x00AF},
// {0xFFE4, 0x00A6},
// {0xFFE5, 0x00A5},
// {0xFFE6, 0x20A9},
//}
//
//// 从strings包拷贝,因此不必导入strings包即可使用本函数。
//var Map = strings.Map
//
//// 判断一个字符是否是半角字符
//func IsSBC(c rune) bool {
// switch {
// case c <= 0x007E:
// case c == 0x00A2 || c == 0x00A3:
// case c == 0x00A5 || c == 0x00A6:
// case c == 0x00AC || c == 0x00AF:
// case c == 0x20A9:
// case c == 0x2985 || c == 0x2986:
// case c >= 0xFF61 && c <= 0xFF9F:
// case c >= 0xFFA0 && c <= 0xFFBE:
// case c >= 0xFFC2 && c <= 0xFFC7:
// case c >= 0xFFCA && c <= 0xFFCF:
// case c >= 0xFFD2 && c <= 0xFFD7:
// case c >= 0xFFDA && c <= 0xFFDC:
// case c >= 0xFFE8 && c <= 0xFFEE:
// default:
// return false
// }
// return true
//}
//
//// 如果字符c为全角字符,返回对应半角字符(如有);否则返回c。
//func ToDBC(c rune) rune {
// switch {
// case c <= 0x218F:
// return c
// case c <= 0x2193:
// case c == 0x2502:
// return 0xFFE8
// case c == 0x25A0:
// return 0xFFED
// case c == 0x25CB:
// return 0xFFEE
// case c <= 0x2FFF:
// return c
// case c <= 0x30FC:
// case c <= 0x3130:
// return c
// case c <= 0x314E:
// return c + 0xCE70
// case c <= 0x3164:
// case c <= 0xFF00:
// return c
// case c <= 0xFF5E:
// return c - 0xFEE0
// case c >= 0xFFE7:
// return c
// }
// i := sort.Search(len(toDBC), func(i int) bool { return toDBC[i].x >= c })
// if toDBC[i].x == c {
// return toDBC[i].y
// } else {
// return c
// }
//}
//
//// 如果字符c为半角字符,返回对应全角字符(如有);否则返回c。
//func ToSBC(c rune) rune {
// switch {
// case c <= 0x001F:
// return c
// case c == 0x0020:
// return 0x3000
// case c <= 0x007E:
// return c + 0xFEE0
// case c <= 0x00AF:
// case c == 0x20A9:
// return 0xFFE6
// case c == 0x2985:
// return 0xFF5F
// case c == 0x2986:
// return 0xFF60
// case c <= 0xFF60:
// return c
// case c <= 0xFFA0:
// case c <= 0xFFBE:
// return c - 0xCE70
// case c >= 0xFFEF:
// return c
// }
// i := sort.Search(len(toSBC), func(i int) bool { return toSBC[i].x >= c })
// if toSBC[i].x == c {
// return toSBC[i].y
// } else {
// return c
// }
//}
//
//// 如果字符c为全角ASCII字符,返回对应的半角字符;否则返回c。
//func ToASCIIDBC(r rune) rune {
// if r == 0x3000 {
// return 0x3000
// }
// if r >= 0xFF01 && r <= 0xFF5E {
// return r - 0xFEE0
// }
// return r
//}
//
//// 如果字符c为半角ASCII字符,返回对应的全角字符;否则返回c。
//func ToASCIISBC(r rune) rune {
// if r == 0x0020 {
// return 0x3000
// }
// if r >= 0x0021 && r <= 0x007E {
// return r + 0xFEE0
// }
// return r
//}
package jeffutil
func CheckCRC(buf []byte) bool {
var wCrcData uint16 = 0xffff
for _, v := range buf {
wCrcData ^= uint16(v)
for j := 0; j < 8; j++ {
if wCrcData&1 != 0 {
wCrcData >>= 1
wCrcData ^= 0xa001
} else {
wCrcData >>= 1
}
}
}
return wCrcData == 0
}
// GetCRC 获取2个字节的CRC16
func GetCRC(buf []byte, len int) { //传入的切片必须装得下
var wCrcData uint16 = 0xffff
for i := 0; i < len; i++ {
wCrcData ^= uint16(buf[i])
for j := 0; j < 8; j++ {
if wCrcData&1 != 0 {
wCrcData >>= 1
wCrcData ^= 0xa001
} else {
wCrcData >>= 1
}
}
}
buf[len] = byte(wCrcData)
buf[len+1] = byte(wCrcData >> 8)
}
package jeffutil
import (
"encoding/base64"
"errors"
)
func EncryptBytesToBase64(cleartext []byte, pswd string, iv string) (base64Result []byte) { //看base64库,返回切片更快,本来tcp发送也是切片,不过这里面string也是切片
var pswdIv [16]byte
var pswdSum byte
var i int
cleartextLen := len(cleartext)
var result = make([]byte, cleartextLen+1)
for i = 0; i < 16; i++ {
pswdIv[i] = ((pswd[i] & 0xaa) | (pswd[15-i] & 0x55)) + iv[15-i] + byte(i)
if i%2 == 0 {
pswdSum += pswd[i] + iv[i]
} else {
pswdSum -= pswd[i] - iv[i]
}
}
for i = 0; i < 16; i++ {
if i%2 == 0 {
pswdIv[i] = ^pswdIv[i] + pswdSum
} else {
pswdIv[i] = pswdIv[i] - ^pswdSum
}
}
result[cleartextLen] = ^pswdSum
for i = 0; i < cleartextLen; i++ {
result[cleartextLen] += cleartext[i]
}
for i = 0; i < cleartextLen; i++ {
result[i] = ^((cleartext[i] & 0x72) | (cleartext[cleartextLen-1-i] & 0x8d))
if i%2 == 0 {
result[i] += pswdIv[i%16] - result[cleartextLen]
} else {
result[i] -= pswdIv[i%16] + result[cleartextLen]
}
}
base64Result = make([]byte, base64.StdEncoding.EncodedLen(cleartextLen+1)+2) //多出两个用来装起始结束符
base64.StdEncoding.Encode(base64Result[1:], result)
return
//return base64.StdEncoding.EncodeToString(result)
}
// DecryptBase64ToBytes 解密并转换为bytes
func DecryptBase64ToBytes(ciphertext []byte, pswd string, iv string) ([]byte, error) { //看base64库,传入切片更快,本来tcp接收也是切片,不过这里面string也是切片
var pswdIv [16]byte
var pswdSum byte
var i int
cipherBytes := make([]byte, base64.StdEncoding.DecodedLen(len(ciphertext)))
hexLen, err := base64.StdEncoding.Decode(cipherBytes, ciphertext)
//cipherBytes, err := base64.StdEncoding.DecodeString(ciphertext)
if err != nil {
return nil, err
}
clearLen := hexLen - 1
var resultBytes = make([]byte, clearLen)
var resultBytesTemp = make([]byte, clearLen)
for i = 0; i < 16; i++ {
pswdIv[i] = ((pswd[i] & 0xaa) | (pswd[15-i] & 0x55)) + iv[15-i] + byte(i)
if i%2 == 0 {
pswdSum += pswd[i] + iv[i]
} else {
pswdSum -= pswd[i] - iv[i]
}
}
for i = 0; i < 16; i++ {
if i%2 == 0 {
pswdIv[i] = ^pswdIv[i] + pswdSum
} else {
pswdIv[i] = pswdIv[i] - ^pswdSum
}
}
for i = 0; i < clearLen; i++ {
if i%2 == 0 {
resultBytesTemp[i] = ^(cipherBytes[i] - (pswdIv[i%16] - cipherBytes[clearLen]))
} else {
resultBytesTemp[i] = ^(cipherBytes[i] + (pswdIv[i%16] + cipherBytes[clearLen]))
}
}
var sum byte
for i = 0; i < clearLen; i++ {
resultBytes[i] = (resultBytesTemp[i] & 0x72) | (resultBytesTemp[clearLen-1-i] & 0x8d)
sum += resultBytes[i]
}
sum += ^pswdSum
if sum != cipherBytes[clearLen] {
return nil, errors.New("密文校验错误")
}
return resultBytes, nil
}
package jeffutil
import (
"fmt"
"testing"
)
//测试用例文件使用 go test 指令来执行,没有也不需要 main() 作为函数入口
//所有在以_test结尾的源码内以Test开头的函数会自动被执行。
func TestHex2Cipher(t *testing.T) {
a := "abcABC哈哈哈就glad就是理工科,的垃圾疯狂的建安费、放大算法。dfafajdf!!"
fmt.Println(a)
fmt.Println(DBCtoSBC(a))
//password := "DCRYM-2018-pswd."
//iv := "I can't tell YOU"
//
//type HexData struct {
// TimeUtc uint32
// DevType uint8
// DevID uint32
// CtrlCode uint8
// Length uint8
// Data []byte
//}
//sData := HexData{
// 1626766761,
// 0x3E,
// 0x000001,
// 0x41,
// 201,//15,
// []byte{
// 0, //通讯延迟
// 0x00, //状态码
// 0x01,0x00, //左电流
// 0x02,0x00, //右电流
// 0x03,0x00, //左电阻
// 0x04,0x00, //右电阻
// 0x05, //左温度
// 0x06, //右温度
// 0x07, //VCC_H
// 0x08, //VCC_L
// 0, //正在使用的用户数
// },
//}
//sData.Length = 243 // 255 267 362 // 243 255 346
//fmt.Println("sData.Length:",sData.Length)
//hexBuf := make([]byte, int(sData.Length) + 12)
//hexBuf[0] = byte(sData.TimeUtc >> 24)
//hexBuf[1] = byte(sData.TimeUtc >> 16)
//hexBuf[2] = byte(sData.TimeUtc >> 8)
//hexBuf[3] = byte(sData.TimeUtc)
//hexBuf[4] = sData.DevType
//hexBuf[5] = byte(sData.DevID >> 16)
//hexBuf[6] = byte(sData.DevID >> 8)
//hexBuf[7] = byte(sData.DevID)
//hexBuf[8] = sData.CtrlCode
//hexBuf[9] = sData.Length
//sData.Data = make([]byte,sData.Length)
////if sData.Length>0 {
//copy(hexBuf[10:],sData.Data[:sData.Length])
////}
//fmt.Println("len(hexBuf)",len(hexBuf))
//GetCRC(hexBuf,int(sData.Length)+10)
//sendStr := EncryptBytesToBase64(hexBuf,password,iv)
//
//sendStr[0] = '{'
//sendStr[len(sendStr) - 1] = '}'
//
//fmt.Printf("string(sendStr):%s\nlen:%d\n",string(sendStr),len(sendStr))
}
//func main() {
// a := "4769676162697445746865726E6574302F302F323400"
// bs, err := hex.DecodeString(a)
// if err != nil {
// panic(err)
// }
// fmt.Println(string(bs))
//}
package jeffutil
import (
"go.uber.org/zap/zapcore"
"gopkg.in/ini.v1"
// "jeff_workstation_1/logger"
"time"
)
var (
HttpServerMode string
HttpServerPort string
HttpClientBaseUrl string
HttpClientTimeOut time.Duration
TcpLongPort string
TcpLongMaxConnections int
TcpLongNewConnReadDeadline time.Duration
TcpLongNewConnRightfulTimeout int64
TcpLongOldConnReadDeadline time.Duration
LogLevel zapcore.Level
LogPath string
LogFileMaxSize int // 单个日志文件的最大MB
LogInfoMaxFileNum int
LogInfoMaxFileDay int
LogWarnMaxFileNum int
LogWarnMaxFileDay int
LogErrorMaxFileNum int
LogErrorMaxFileDay int
)
func init() {
file, err := ini.Load("./config.ini")
if err != nil {
// logger.Log.Panic("配置文件读取错误")
panic("配置文件读取错误")
}
HttpServerMode = file.Section("http_server").Key("ServerMode").In("release", []string{"release", "debug"})
HttpServerPort = file.Section("http_server").Key("ServerPort").MustString(":50000")
HttpClientBaseUrl = file.Section("http_client").Key("BaseUrl").MustString("http://handandev.swaylink.cn/phone/2/server/")
HttpClientTimeOut = time.Duration(file.Section("http_client").Key("TimeOut").MustInt(5)) * time.Second
TcpLongPort = file.Section("tcp_long_server").Key("TcpPort").MustString("60000")
TcpLongMaxConnections = int(file.Section("tcp_long_server").Key("MaxConnections").MustUint(20000))
TcpLongNewConnReadDeadline = time.Duration(file.Section("tcp_long_server").Key("NewConnReadDeadline").MustInt(60)) * time.Second
TcpLongNewConnRightfulTimeout = file.Section("tcp_long_server").Key("NewConnRightfulTimeout").MustInt64(120)
TcpLongOldConnReadDeadline = time.Duration(file.Section("tcp_long_server").Key("OldConnReadDeadline").MustInt(180)) * time.Second
logLvlStr := file.Section("log").Key("Level").In("warn", []string{"trace", "debug", "info", "warn", "error"})
switch logLvlStr {
case "debug":
LogLevel = zapcore.DebugLevel
case "info":
LogLevel = zapcore.InfoLevel
case "warn":
LogLevel = zapcore.WarnLevel
case "error":
LogLevel = zapcore.ErrorLevel
}
LogPath = file.Section("log").Key("Path").MustString(".log")
LogFileMaxSize = file.Section("log").Key("FileMaxSize").MustInt(10)
LogInfoMaxFileNum = file.Section("log").Key("InfoMaxFileNum").MustInt(10)
LogInfoMaxFileDay = file.Section("log").Key("InfoWithMaxAge").MustInt(30)
LogWarnMaxFileNum = file.Section("log").Key("WarnMaxFileNum").MustInt(10)
LogWarnMaxFileDay = file.Section("log").Key("WarnWithMaxAge").MustInt(90)
LogErrorMaxFileNum = file.Section("log").Key("ErrorMaxFileNum").MustInt(10)
LogErrorMaxFileDay = file.Section("log").Key("ErrorWithMaxAge").MustInt(180)
//LogTraceWithRotationTime = time.Duration(file.Section("log").Key("TraceWithRotationTime").MustInt(2)) * time.Hour
//LogTraceWithMaxAge = time.Duration(file.Section("log").Key("TraceWithMaxAge").MustInt(24)) * time.Hour
//
//LogDebugWithRotationTime = time.Duration(file.Section("log").Key("DebugWithRotationTime").MustInt(2)) * time.Hour
//LogDebugWithMaxAge = time.Duration(file.Section("log").Key("DebugWithMaxAge").MustInt(24)) * time.Hour
//
//LogInfoWithRotationTime = time.Duration(file.Section("log").Key("InfoWithRotationTime").MustInt(24)) * time.Hour
//LogInfoWithMaxAge = time.Duration(file.Section("log").Key("InfoWithMaxAge").MustInt(3*24)) * time.Hour
//
//LogWarnWithRotationTime = time.Duration(file.Section("log").Key("WarnWithRotationTime").MustInt(24)) * time.Hour
//LogWarnWithMaxAge = time.Duration(file.Section("log").Key("WarnWithMaxAge").MustInt(7*24)) * time.Hour
//
//LogErrorWithRotationTime = time.Duration(file.Section("log").Key("ErrorWithRotationTime").MustInt(10*24)) * time.Hour
//LogErrorWithMaxAge = time.Duration(file.Section("log").Key("ErrorWithMaxAge").MustInt(30*24)) * time.Hour
}
#!/bin/bash
filename="TcpServer"
port=50000
cnt=`netstat -tnlp|grep $port |grep -v grep |wc -l`
#cne=`ps -ef|grep $filename|grep -v grep |wc -l`
if [[ $cnt -eq 0 ]];then
cd /root/
nohup ./$filename &
fi
\ No newline at end of file
package logger
import (
"github.com/gin-gonic/gin"
"github.com/natefinch/lumberjack"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"jeff_workstation_1/jeffutil"
"os"
"time"
)
var Log *zap.Logger
func InitLogger() {
config := zapcore.EncoderConfig{
MessageKey: "msg", //结构化(json)输出:msg的key
LevelKey: "level", //结构化(json)输出:日志级别的key(INFO,WARN,ERROR等)
TimeKey: "ts", //结构化(json)输出:时间的key(INFO,WARN,ERROR等)
CallerKey: "file", //结构化(json)输出:打印日志的文件对应的Key
EncodeLevel: zapcore.CapitalLevelEncoder, //将日志级别转换成大写(INFO,WARN,ERROR等)
EncodeCaller: zapcore.ShortCallerEncoder, //采用短文件路径编码输出(test/main.go:14 )
EncodeTime: func(t time.Time, enc zapcore.PrimitiveArrayEncoder) {
enc.AppendString(t.Format("2006-01-02 15:04:05.000"))
}, //输出的时间格式
//EncodeDuration: func(d time.Duration, enc zapcore.PrimitiveArrayEncoder) {
// enc.AppendInt64(int64(d) / 1000000)
//},//
}
//debug info
infoLevel := zap.LevelEnablerFunc(func(lvl zapcore.Level) bool {
return lvl < zapcore.WarnLevel && lvl >= jeffutil.LogLevel
})
//warn
warnLevel := zap.LevelEnablerFunc(func(lvl zapcore.Level) bool {
return lvl == zapcore.WarnLevel && lvl >= jeffutil.LogLevel
})
//error DPanic Panci Fatal
errorLevel := zap.LevelEnablerFunc(func(lvl zapcore.Level) bool {
return lvl > zapcore.WarnLevel && lvl >= jeffutil.LogLevel
})
infoWriter := &lumberjack.Logger{
Filename: jeffutil.LogPath + "info.log",
MaxSize: jeffutil.LogFileMaxSize, //最大M数,超过则切割
MaxBackups: jeffutil.LogInfoMaxFileNum, //最大文件保留数,超过就删除最老的日志文件
MaxAge: jeffutil.LogInfoMaxFileDay, //保存30天
Compress: false, //是否压缩
}
warnWriter := &lumberjack.Logger{
Filename: jeffutil.LogPath + "warn.log",
MaxSize: jeffutil.LogFileMaxSize, //最大M数,超过则切割
MaxBackups: jeffutil.LogWarnMaxFileNum, //最大文件保留数,超过就删除最老的日志文件
MaxAge: jeffutil.LogWarnMaxFileDay, //保存30天
Compress: false, //是否压缩
}
errorWriter := &lumberjack.Logger{
Filename: jeffutil.LogPath + "error.log",
MaxSize: jeffutil.LogFileMaxSize, //最大M数,超过则切割
MaxBackups: jeffutil.LogErrorMaxFileNum, //最大文件保留数,超过就删除最老的日志文件
MaxAge: jeffutil.LogErrorMaxFileDay, //保存30天
Compress: false, //是否压缩
}
core := zapcore.NewTee(
zapcore.NewCore(zapcore.NewJSONEncoder(config), zapcore.AddSync(infoWriter), infoLevel), // zapcore.NewConsoleEncoder(encoder)
zapcore.NewCore(zapcore.NewJSONEncoder(config), zapcore.AddSync(warnWriter), warnLevel), //
zapcore.NewCore(zapcore.NewJSONEncoder(config), zapcore.AddSync(errorWriter), errorLevel), //
//zapcore.NewCore(zapcore.NewJSONEncoder(encoder), zapcore.NewMultiWriteSyncer(zapcore.AddSync(os.Stdout)), logLevel),//同时将日志输出到控制台,NewJSONEncoder 是结构化输出
)
Log = zap.New(core, zap.AddStacktrace(zap.ErrorLevel))
}
func HttpGinLog() gin.HandlerFunc { //logger *log.Log
return func(c *gin.Context) {
startTime := time.Now().UnixNano()
c.Next()
// stopTime := time.Since(startTime)
// spendTime := stopTime.Nanoseconds()/1000000///fmt.Sprintf("%d ms", (stopTime.Nanoseconds()+500000)/1000000)
spendTime := time.Now().UnixNano() - startTime
hostName, err := os.Hostname()
if err != nil {
hostName = "unknown"
}
statusCode := c.Writer.Status()
clientIp := c.ClientIP()
userAgent := c.Request.UserAgent()
dataSize := c.Writer.Size()
if dataSize < 0 {
dataSize = 0
}
method := c.Request.Method
path := c.Request.RequestURI
//c.Request.Body.Read()
//body := c.Request.Body
//para := c.Params
//entry := Log.WithFields(log.Fields{
// "HostName": hostName,
// "Status": statusCode,
// "SpendNanoS": spendTime,
// "Ip": clientIp,
// "Method": method,
// "Path": path,
// "DataSize": dataSize,
// "Agent": userAgent,
//})
if len(c.Errors) > 0 {
//entry.Error(c.Errors.ByType(gin.ErrorTypePrivate).String())
Log.Error(c.Errors.ByType(gin.ErrorTypePrivate).String(),
zap.String("HostName", hostName),
zap.Int("Status", statusCode),
zap.Int64("SpendNanoS", spendTime),
zap.String("Ip", clientIp),
zap.String("Method", method),
zap.String("Path", path),
zap.Int("DataSize", dataSize),
zap.String("Agent", userAgent))
}
if statusCode >= 500 {
Log.Error("",
zap.String("HostName", hostName),
zap.Int("Status", statusCode),
zap.Int64("SpendNanoS", spendTime),
zap.String("Ip", clientIp),
zap.String("Method", method),
zap.String("Path", path),
zap.Int("DataSize", dataSize),
zap.String("Agent", userAgent))
} else if statusCode >= 400 {
Log.Warn("",
zap.String("HostName", hostName),
zap.Int("Status", statusCode),
zap.Int64("SpendNanoS", spendTime),
zap.String("Ip", clientIp),
zap.String("Method", method),
zap.String("Path", path),
zap.Int("DataSize", dataSize),
zap.String("Agent", userAgent))
} else {
Log.Info("",
zap.String("HostName", hostName),
zap.Int("Status", statusCode),
zap.Int64("SpendNanoS", spendTime),
zap.String("Ip", clientIp),
zap.String("Method", method),
zap.String("Path", path),
zap.Int("DataSize", dataSize),
zap.String("Agent", userAgent))
}
}
}
//import (
// "github.com/gin-gonic/gin"
// rotatelogs "github.com/lestrrat-go/file-rotatelogs"
// "github.com/rifflock/lfshook"
// log "github.com/sirupsen/logrus"
// "jeff_workstation_1/jeffutil"
// "os"
// "time"
//)
//
//func InitLogger(filePath string){
//
// // log.SetOutput(colorable.NewColorableStdout())
//
// // log.SetOutput(f)
// log.SetLevel(jeffutil.LogLevel)
//
// TraceLogWriter,_ := rotatelogs.New(
// filePath+"Trace_%Y%m%d%H.log",
// rotatelogs.WithMaxAge(jeffutil.LogTraceWithMaxAge),
// rotatelogs.WithRotationTime(jeffutil.LogTraceWithRotationTime),
// //rotatelogs.WithLinkName(linkName),
// )
// DebugLogWriter,_ := rotatelogs.New(
// filePath+"Debug_%Y%m%d%H.log",
// rotatelogs.WithMaxAge(jeffutil.LogDebugWithMaxAge),
// rotatelogs.WithRotationTime(jeffutil.LogDebugWithRotationTime),
// //rotatelogs.WithLinkName(linkName),
// )
// infoLogWriter,_ := rotatelogs.New(
// filePath+"Info_%Y%m%d%H.log",
// rotatelogs.WithMaxAge(jeffutil.LogInfoWithMaxAge),
// rotatelogs.WithRotationTime(jeffutil.LogInfoWithRotationTime),
// //rotatelogs.WithLinkName("tcp_info.log"),
// )
// WarnLogWriter,_ := rotatelogs.New(
// filePath+"Warn_%Y%m%d%H.log",
// rotatelogs.WithMaxAge(jeffutil.LogWarnWithMaxAge),
// rotatelogs.WithRotationTime(jeffutil.LogWarnWithRotationTime),
// //rotatelogs.WithLinkName("tcp_warn.log"),
// )
// ErrorLogWriter,_ := rotatelogs.New(
// filePath+"Error_%Y%m%d%H.log",
// rotatelogs.WithMaxAge(jeffutil.LogErrorWithMaxAge),
// rotatelogs.WithRotationTime(jeffutil.LogErrorWithRotationTime),
// //rotatelogs.WithLinkName("tcp_error.log"),
// )
//
// writeMap := lfshook.WriterMap{
// log.TraceLevel: TraceLogWriter,
// log.DebugLevel: DebugLogWriter,
// log.InfoLevel: infoLogWriter,
// log.WarnLevel: WarnLogWriter,
// log.ErrorLevel: ErrorLogWriter,
// log.PanicLevel: ErrorLogWriter,
// log.FatalLevel: ErrorLogWriter,
// }
// hook := lfshook.NewHook(writeMap,&log.JSONFormatter{
// TimestampFormat: "2006-01-02 15:04:05.000000",
// })
//
// log.AddHook(hook)
// return
//}
//
//func HttpGinLog() gin.HandlerFunc{ //logger *log.Log
// return func(c *gin.Context) {
// startTime := time.Now().UnixNano()
// c.Next()
// //stopTime := time.Since(startTime)
// //spendTime := stopTime.Nanoseconds()/1000000///fmt.Sprintf("%d ms", (stopTime.Nanoseconds()+500000)/1000000)
// spendTime := time.Now().UnixNano() - startTime
// hostName, err := os.Hostname()
// if err != nil {
// hostName = "unknown"
// }
// statusCode := c.Writer.Status()
// clientIp := c.ClientIP()
// userAgent := c.Request.UserAgent()
// dataSize := c.Writer.Size()
// if dataSize < 0 {
// dataSize = 0
// }
// method := c.Request.Method
// path := c.Request.RequestURI
//
// //c.Request.Body.Read()
// //body := c.Request.Body
// //para := c.Params
//
// entry := log.WithFields(log.Fields{
// "HostName": hostName,
// "Status": statusCode,
// "SpendNanoS": spendTime,
// "Ip": clientIp,
// "Method": method,
// "Path": path,
// "DataSize": dataSize,
// "Agent": userAgent,
// })
//
// if len(c.Errors) > 0 {
// entry.Error(c.Errors.ByType(gin.ErrorTypePrivate).String())
// }
// if statusCode >= 500 {
// entry.Error()
// } else if statusCode >= 400 {
// entry.Warn()
// } else {
// entry.Info()
// }
// }
//}
package main
import (
"github.com/gin-gonic/gin"
dcphone10 "jeff_workstation_1/devproduct/dcphone10"
"jeff_workstation_1/jeffutil"
"jeff_workstation_1/logger"
"os"
"syscall"
)
//windows
//var (
// kernel32 = syscall.MustLoadDLL("kernel32.dll")
// procSetStdHandle = kernel32.MustFindProc("SetStdHandle")
//)
//
//func setStdHandle(stdhandle int32, handle syscall.Handle) error {
// r0, _, e1 := syscall.Syscall(procSetStdHandle.Addr(), 2, uintptr(stdhandle), uintptr(handle), 0)
// if r0 == 0 {
// if e1 != 0 {
// return error(e1)
// }
// return syscall.EINVAL
// }
// return nil
//}
//
//// redirectStderr to the file passed in
//func redirectStderrWindows(f *os.File) {
// err := setStdHandle(syscall.STD_ERROR_HANDLE, syscall.Handle(f.Fd()))
// if err != nil {
// logger.Log.Panic(err.Error())
// }
// // SetStdHandle does not affect prior references to stderr
// os.Stderr = f
//}
//windows end
func redirectStderrLinux(f *os.File) {
err := syscall.Dup2(int(f.Fd()), int(os.Stderr.Fd()))
if err != nil {
logger.Log.Panic(err.Error())
}
}
func init() {
logger.InitLogger()
f, err := os.OpenFile(jeffutil.LogPath+"panic.log", os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0755)
if err != nil {
logger.Log.Panic(err.Error())
}
//redirectStderrWindows(f)
redirectStderrLinux(f)
}
// dcfan50 "jeff_workstation_1/devproduct/dcfan50"
// dcphone10 "jeff_workstation_1/devproduct/dcphone10"
func main() { //
gin.SetMode(jeffutil.HttpServerMode)
r := gin.New()
r.Use(logger.HttpGinLog(), gin.Recovery())
//r.Use()
// dcfan50.NewDCFan50(r)
dcphone10.NewDCPhone10(r)
err := r.Run(jeffutil.HttpServerPort)
if err != nil {
panic(err)
}
}
package main
import (
"testing"
)
func Test(t *testing.T) {
//jeffutil.init()
}
//
//import (
// log "github.com/sirupsen/logrus"
// "os"
// "syscall"
// "testing"
//)
//
//var (
// kernel32 = syscall.MustLoadDLL("kernel32.dll")
// procSetStdHandle = kernel32.MustFindProc("SetStdHandle")
//)
//
//func setStdHandle(stdhandle int32, handle syscall.Handle) error {
// r0, _, e1 := syscall.Syscall(procSetStdHandle.Addr(), 2, uintptr(stdhandle), uintptr(handle), 0)
// if r0 == 0 {
// if e1 != 0 {
// return error(e1)
// }
// return syscall.EINVAL
// }
// return nil
//}
//
//// redirectStderr to the file passed in
//func redirectStderrWindows(f *os.File) {
// err := setStdHandle(syscall.STD_ERROR_HANDLE, syscall.Handle(f.Fd()))
// if err != nil {
// log.Fatalf("Failed to redirect stderr to file: %v\n", err)
// }
// // SetStdHandle does not affect prior references to stderr
// os.Stderr = f
//}
//
//
//// redirectStderr to the file passed in
////func redirectStderrLinux(f *os.File) {
//// err := syscall.Dup2(int(f.Fd()), int(os.Stderr.Fd()))
//// if err != nil {
//// log.Fatalf("Failed to redirect stderr to file: %v\n", err)
//// }
////}
//
//
//func Test(t *testing.T) {
// f, err := os.OpenFile("./golang_log.log", os.O_CREATE|os.O_APPEND|os.O_WRONLY,0755)
// if err != nil{
// log.Fatalln(err)
// }
//
// redirectStderrWindows(f)
//
// log.SetOutput(f)
//
// log.Println("1234")
// var testPanic []byte
// testPanic[0] = 1
// // log.Panicln("log.Panicln")
//}
//package main
//
//import (
// "log"
// "os"
// "syscall"
// "testing"
//)
//
//
//var (
// kernel32 = syscall.MustLoadDLL("kernel32.dll")
// procSetStdHandle = kernel32.MustFindProc("SetStdHandle")
//)
//
//func setStdHandle(stdhandle int32, handle syscall.Handle) error {
// r0, _, e1 := syscall.Syscall(procSetStdHandle.Addr(), 2, uintptr(stdhandle), uintptr(handle), 0)
// if r0 == 0 {
// if e1 != 0 {
// return error(e1)
// }
// return syscall.EINVAL
// }
// return nil
//}
//
//// redirectStderr to the file passed in
//func redirectStderrWindows(f *os.File) {
// err := setStdHandle(syscall.STD_ERROR_HANDLE, syscall.Handle(f.Fd()))
// if err != nil {
// log.Fatalf("Failed to redirect stderr to file: %v\n", err)
// }
// // SetStdHandle does not affect prior references to stderr
// os.Stderr = f
//}
//
//
//// redirectStderr to the file passed in
////func redirectStderrLinux(f *os.File) {
//// err := syscall.Dup2(int(f.Fd()), int(os.Stderr.Fd()))
//// if err != nil {
//// log.Fatalf("Failed to redirect stderr to file: %v\n", err)
//// }
////}
//
//
//func Test(t *testing.T) {
// f, err := os.OpenFile("./golang_log.log", os.O_CREATE|os.O_APPEND|os.O_WRONLY,0755)
// if err != nil{
// log.Fatalln(err)
// }
//
// redirectStderrWindows(f)
//
// log.SetOutput(f)
// log.SetFlags(log.Ldate|log.Ltime|log.Lmicroseconds|log.Llongfile)
//
// log.Println("1234")
// var testPanic []byte
// testPanic[0] = 1
// // log.Panicln("log.Panicln")
//}
. 编译成linux的可执行文件
. 编译成linux的可执行文件
1. set GOARCH=amd64
2. set GOOS=linux set GOOS=windows
3. go build -o TcpServer -ldflags "-w -s" main.go
windows编译 go build -o phoneDevServer.exe -ldflags "-w -s -H windowsgui" main.go
前台要打印 go build -ldflags "-w -s" main.go
linux 基本命令
rz 上传文件 (安装 yum install lrzsz)
chmod +x fileName 设置为可执行文件
nohup ./fileName & 后台运行
sz 下载文件
netstat -nltp 看端口
kill -9 进程号 杀掉进程
tail -10f Info_20210730.log 实时监视日志
rm -f fileName 删除文件
rm -f ./* 删除文件夹下所有文件
top 查看服务器占用情况
// 仅监视进程,修改filename和路径/root/XXXXX
#!/bin/bash
filename=TcpServer
port=50000
cnt=`netstat -tnlp|grep $port |grep -v grep |wc -l`
#cne=`ps -ef|grep $filename|grep -v grep |wc -l`
if [[ $cnt -eq 0 ]];then
cd /root/
nohup ./$filename &
fi
// 把.sh文件拷贝过去执行crontab -e,a进入编辑,第一行:* * * * * sleep 10;/bin/sh /root/watchtcpserver.sh,esc->:wq
// sh watchtcpserver.sh 直接执行脚本
// 监视端口和进程,修改filename和路径/root/XXXXX
#!/bin/bash
filename=TcpServer
port=50000
cnt=`netstat -tnlp|grep $port |grep -v grep |wc -l`
cne=`ps -ef|grep $filename|grep -v grep |wc -l`
if [[ $cnt -eq 0 ]] || [[ $cne -eq 0 ]];then
cd /root/
nohup ./$filename &
fi
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment