This is a creation in Article, where the information may have evolved or changed.
The front end connects to the access server via UDP, and the Access server maintains a TCP connection with the back-end TCP server. Directory structure and back-end TCP server code previous blog.
Main.go
Package Main Import ( "Lotuslib")const ( ip = "0.0.0.0" = 1987) Func Main () { udplotus. Udplotusmain (IP, port)}
Udplotus.go
PackageUdplotusImport ( "Encoding/json" "Log" "Net" "StrConv" "Time")Const(Proxy_timeout= 5Proxy_server= "127.0.0.1:1988"msg_length= 1024) type Request struct {reqIdintreqcontent string Rspchan chan<-string//WriteOnly Chan}var requestmap map[int]*RequestType clienter struct {client net. Conn isAlive bool Sendstr Chan*Request Recvstr Chan String}func (c*clienter) Connect () bool {ifc.isalive {return true } Else{var err error c.client, err= Net. Dial ("TCP", Proxy_server)ifErr! =Nil {return false} c.isalive=truelog. Println ("Connect to" +proxy_server)} return true}func Proxysendloop (c*clienter) { //store reqId and ReqcontentSendData: =Make (map[string]string) for { if!c.isalive {time. Sleep (1 *Time . Second) C.connect ()}ifc.isalive {req:= <-C.sendstr//construct request JSON stringsenddata["reqId"] =StrConv. Itoa (req.reqid) senddata["Reqcontent"] =req.reqcontent Sendjson, err:=JSON. Marshal (SendData)ifErr! =Nil {Continue} _, Err= C.client.write ([]byte(Sendjson))ifErr! =Nil {c.recvstr<-string ("Proxy server close ...") c.client.close () c.isalive=falselog. Println ("Disconnect from" +proxy_server)Continue } //log. Println ("Write to Proxy Server:" + string (Sendjson))}}}func Proxyrecvloop (c*clienter) {buf:= Make ([]byte, Msg_length) RecvData:= Make (map[string]string, 2) for { if!c.isalive {time. Sleep (1 *Time . Second) C.connect ()}ifc.isalive {n, err:=C.client.read (BUF)ifErr! =Nil {c.client.close () c.isalive=falselog. Println ("Disconnect from" +proxy_server)Continue } //log. Println ("Read from Proxy Server:" + string (Buf[0:n])) ifERR: = json. Unmarshal (Buf[0:n], &recvdata); Err = =Nil {reqidstr:= recvdata["ReqId"] ifReqid, err: = StrConv. Atoi (REQIDSTR); Err = =Nil {req, OK:=Requestmap[reqid]if!OK {Continue} Req.rspchan<-recvdata["Rescontent"] } Continue}}}}func handle (conn*net. Udpconn, remote *net. UDPADDR, IDint, TC *clienter, data []byte) {handleproxy:=Make (Chan string) Request:= &request{reqid:id, rspchan:handleproxy} request.reqcontent=string (data) Requestmap[id]=Request//Send to ProxySelect { CaseTc. Sendstr <-Request: Case<-time. After (Proxy_timeout *Time . Second): Conn. WRITETOUDP ([]byte("Proxy Server send timeout.")), remote)}//read from proxySelect { CaseRspcontent: = <-Handleproxy:conn. WRITETOUDP ([]byte(rspcontent), remote) Case<-time. After (Proxy_timeout *Time . Second): Conn. WRITETOUDP ([]byte("Proxy server recv timeout.")), remote)}}func udplotusmain (IP string, portint) { //Start TCP ServerAddr, Err: = Net. RESOLVEUDPADDR ("UDP", ip+ ":" +StrConv. Itoa (port))ifErr! =Nil {log. Fatalln ("NET. Resolveudpaddr fail. ", Err)return} conn, err:= Net. LISTENUDP ("UDP", addr)ifErr! =Nil {log. Fatalln ("NET. LISTENUDP fail. ", Err)//OS. Exit (1) return} log. Println ("Start UDP server" + IP + "" +StrConv. Itoa (port)) defer Conn. Close ()//start proxy connect and loopvar TC clienter TC. Sendstr= Make (Chan *request, 1000) TC. Recvstr=Make (Chan string) tc. Connect () Go Proxysendloop (&tc) Go Proxyrecvloop (&TC)//Listen new RequestRequestmap = Make (map[int]*Request) BUF:= Make ([]byte, msg_length) var idint= 0 for{rlen, remote, err:=Conn. READFROMUDP (BUF)ifErr = =Nil {ID++log. Println ("Connected from" +remote. String ()) go handle (conn, remote, ID,&TC, Buf[:rlen])//New Thread } }}
Udpclient.go
PackageMainImport ( "Bufio" "FMT" "NET" "OS") Func main () {addr, err:= Net. RESOLVEUDPADDR ("UDP", ": 1987") ifErr! =Nil {fmt. Println ("NET. Resolveudpaddr fail. ", err) os. Exit (1)} socket, err:= Net. DIALUDP ("UDP", nil, addr)ifErr! =Nil {fmt. Println ("NET. DIALUDP fail. ", err) os. Exit (1)} defer socket. Close () R:=Bufio. Newreader (OS. Stdin) for { SwitchLine, OK: = r.readstring (' \ n ');true { CaseOk! =nil:fmt. Printf ("Bye bye!\n") return default: Socket. Write ([]byte(line)) Data:= Make ([]byte, 1024) _, Remoteaddr, err:=socket. READFROMUDP (data)ifErr! =Nil {fmt. Println ("Error recv Data") return} fmt. Printf ("From%s:%s\n", Remoteaddr.string (), String (data)} }}