golang socket服务器

golang socket服务器,第1张

概述一、main.go该代码从项目中分离出来,自行修改后再运行) package mainimport ( "flag" "fmt" "log" "os" "runtime")var ( Port           = flag.String("i", ":12345", "IP port to listen on") logFileName    = flag.String

一、main.go该代码从项目中分离出来,自行修改后再运行)

packagemainimport(	"flag"	"fmt"	"log"	"os"	"runtime")var(	Port=flag.String("i",":12345","IPporttoListenon")	logfilename=flag.String("log","cServer.log","Logfilename")	configfilename=flag.String("configfile","config.ini","Generalconfigurationfile"))var(	configfile=flag.String("configfile","Generalconfigurationfile"))funcmain(){	runtime.GOMAXPROCS(runtime.Numcpu())	flag.Parse()	//setlogfileStdout	logfile,logErr:=os.Openfile(*logfilename,os.O_CREATE|os.O_RDWR|os.O_APPEND,0666)	iflogErr!=nil{		fmt.Println("Failtofind",*logfile,"cServerstartFailed")		os.Exit(1)	}	log.Setoutput(logfile)	log.SetFlags(log.Ldate|log.Ltime|log.Lshortfile)	//setlogfileStdoutEnd	//startListen	ListenErr:=StartListen(*Port)	ifListenErr!=nil{		log.Fatalf("Serverabort!Cause:%v\n",ListenErr)	}}

二、Listener.go该代码从项目中分离出来,自行修改后再运行)

packagemainimport(	"code.Google.com/p/go-uuID/uuID"	"errors"	"fmt"	"goCS/consistent"	"log"	"net"	"sync"	"time")const(	ConnectionMax=100//CSmaxconnect)//connPoolinfovar(	poolLocksync.RWMutex	poolCli[ConnectionMax]*CliInfo)//WebuserinfotypeUserInfostruct{	WS_IDint	WS_namestring	Servicenamestring}//CliinfotypeCliInfostruct{	AssignIDint//csassignID	Connnet.Conn//TheTCP/IPconnectintotheplayer.	ConnTimetime.Time//连接时间	VerifyKeystring//连接验证KEY	ConnVerifybool//是否验证	ServerTypeint32//服务器类型(1DB服务器,2WEB服务器)	NodeStatint32//服务器当前状态(0、宕机;1、正常;2、数据导入中;3、准备中;4、数据迁出中	Addressstring//服务地址	Portint//服务端口	BackupSermap[string]int//备份服务器列表map(ip:port)	sync.RWMutex}typehashPoolstruct{	Versionint	Circlemap[uint32]string//hash圈节点分布	Replicasmap[string]int//hash圈节点范围}varSerHashPool*consistent.Consistent=consistent.New()//ClIEntdisconnectfunc(cli*CliInfo)disconnect(clIEntIDint){	poolLock.Lock()	deferpoolLock.Unlock()	cli.Conn.Close()	log.Printf("ClIEnt:%squit\n",cli.VerifyKey)	ifcli.ServerType==1{		//掉线处理		ifok:=cli.removeDBS();ok{			poolCli[clIEntID]=nil		}	}else{	}}//Listenhandlefunc(cli*CliInfo)ListenHandle(clIEntIDint){	headBuff:=make([]byte,12)//setreadstreamsize	defercli.Conn.Close()	//sendverifyKey:	b:=[]byte(cli.VerifyKey)	cli.Conn.Write(b)	//fmt.Println("cli-IP:",cli.Conn.RemoteAddr().String())	//await10secondverify	cli.Conn.SetDeadline(time.Now().Add(time.Duration(10)*time.Second))	forControl:=true	forforControl{		varheadNumint		forheadNum<cap(headBuff){			readheadNum,readheaderr:=cli.Conn.Read(headBuff[headNum:])			ifreadheaderr!=nil{				log.Println("errhead:",readheaderr)				forControl=false				break			}			headNum+=readheadNum		}		ifheadNum==cap(headBuff){			//packheadHandle			packhead:=packheadAnalysis(headBuff)			bodyBuff:=make([]byte,packhead.PackLen)			varbodyNumint			forbodyNum<cap(bodyBuff){				readBodyNum,readBodyErr:=cli.Conn.Read(bodyBuff[bodyNum:])				ifreadBodyErr!=nil{					log.Println("errBody:",readBodyErr)					forControl=false					break				}				bodyNum+=readBodyNum			}			ifbodyNum==int(packhead.PackLen){				//packbodyHandle				cli.packBodyAnalysis(clIEntID,packhead,bodyBuff)				//fmt.Printf("packType:%d;packOther:%d;packLen:%d\n",packhead.PackType,packhead.PackOther,packhead.PackLen)			}		}	}	cli.disconnect(clIEntID)}//CheckorassignnewconnfuncNewConnection_CS(connnet.Conn)(okbool,indexint,info*CliInfo){	poolLock.Lock()	deferpoolLock.Unlock()	//AssignIDforclIEnt	variint	fori=0;i<ConnectionMax;i++{		ifpoolCli[i]==nil{			break		}	}	//Toomanyconnections	ifi>ConnectionMax{		log.Printf("Toomanyconnections!ActiveDenial%s\n",conn.RemoteAddr().String())		conn.Close()		returnfalse,nil	}	//CreateclIEntbaseinfo	Cli:=new(CliInfo)	Cli.Conn=conn	Cli.ConnTime=time.Now()	Cli.VerifyKey=uuID.New()	Cli.BackupSer=make(map[string]int)	//UpdatePoolinfo	poolCli[i]=Cli	log.Println("CliIDassignok:",i)	returntrue,i,Cli}//startListensfuncStartListen(addrstring)error{	Listener,err:=net.Listen("tcp",addr)	iferr!=nil{		returnerr	}	//ifErrorsacceptarrive100.Listenerstop.	forfailures:=0;failures<100;{		conn,ListenErr:=Listener.Accept()		ifListenErr!=nil{			log.Printf("number:%d,FailedListening:%v\n",failures,ListenErr)			failures++		}		ifok,index,Cli:=NewConnection_CS(conn);ok{			//Anewconnectionisestablished.SpawnanewgoroutingtohandlethatClIEnt.			goCli.ListenHandle(index)		}	}	returnerrors.New("ToomanyListener.Accept()errors,Listenerstop")}

三、原理

一个新的连接建立。产生一个新的gorouting来处理客户端。

一个客户端进来首先分配一个唯一ID,并初始化该客户端的基本信息(见:NewConnection_CS方法),产生一个新的gorouting来处理客户端。

如果服务器达到设定的连接上限,将抛弃该客户端。

客户端连接(分配ID)正常后,将等待10秒来给客户端进行验证超期将断开该客户端连接(见:ListenHandle中的cli.Conn.SetDeadline)。

验证成功后,开接与用户数据进行分析处理:接收原理为:前4字节为包类型,4-12字节为包长,首先接收够12字节后进行包头解析(如不够12字节将进行等待直到够12字节),解析出4-12字节来得到整个包体的长度进行读取(如不够将等待直到够包体长度)

整包读取完后,根据0-4字节判断包的类型进行包的处理。

四、服务器连接出错达到100条后将终止运行

总结

以上是内存溢出为你收集整理的golang socket服务器全部内容,希望文章能够帮你解决golang socket服务器所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1291320.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-10
下一篇 2022-06-10

发表评论

登录后才能评论

评论列表(0条)

保存