Go語言Telnet迴音服務器

package main

import (
   "fmt"
   "net"
   "bufio"
   "strings"
   "os"
)

func main() {

   // 創建一個程序結束碼的通道
   exitChan := make(chan int)

   // 將服務器併發運行
   go server("127.0.0.1:7001", exitChan)

   // 通道阻塞, 等待接收返回值
   code := <-exitChan

   // 標記程序返回值並退出
   os.Exit(code)
}

// 服務邏輯, 傳入地址和退出的通道
func server(address string, exitChan chan int) {

   // 根據給定地址進行偵聽
   l, err := net.Listen("tcp", address)

   // 如果偵聽發生錯誤, 打印錯誤並退出
   if err != nil {
      fmt.Println(err.Error())
      exitChan <- 1
   }

   // 打印偵聽地址, 表示偵聽成功
   fmt.Println("listen: " + address)

   // 延遲關閉偵聽器
   defer l.Close()

   // 偵聽循環
   for {

      // 新連接沒有到來時, Accept是阻塞的
      conn, err := l.Accept()

      // 發生任何的偵聽錯誤, 打印錯誤並退出服務器
      if err != nil {
         fmt.Println(err.Error())
         continue
      }

      // 根據連接開啓會話, 這個過程需要並行執行
      go handleSession(conn, exitChan)
   }
}

// 連接的會話邏輯
func handleSession(conn net.Conn, exitChan chan int) {

   fmt.Println("Session started:")

   // 創建一個網絡連接數據的讀取器
   reader := bufio.NewReader(conn)

   // 接收數據的循環
   for {

      // 讀取字符串, 直到碰到回車返回
      str, err := reader.ReadString('\n')

      // 數據讀取正確
      if err == nil {

         // 去掉字符串尾部的回車
         str = strings.TrimSpace(str)

         // 處理Telnet指令
         if !processTelnetCommand(str, exitChan) {
            conn.Close()
            break
         }

         // Echo邏輯, 發什麼數據, 原樣返回
         conn.Write([]byte(str + "\r\n"))

      } else {
         // 發生錯誤
         fmt.Println("Session closed")
         conn.Close()
         break
      }
   }

}

//命令處理
func processTelnetCommand(str string, exitChan chan int) bool {

   // @close指令表示終止本次會話
   if strings.HasPrefix(str, "@close") {

      fmt.Println("Session closed")

      // 告訴外部需要斷開連接
      return false

      // @shutdown指令表示終止服務進程
   } else if strings.HasPrefix(str, "@shutdown") {

      fmt.Println("Server shutdown")

      // 往通道中寫入0, 阻塞等待接收方處理
      exitChan <- 0

      // 告訴外部需要斷開連接
      return false
   }

   // 打印輸入的字符串
   fmt.Println(str)

   return true

}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章