go實現tcp服務端口轉發

package main

import (
   "fmt"
   "log"
   "net"
   "os"
   "strconv"
   )

func main() {
   //源端口
   argument1 := os.Args[1]
   log.Println( "需要變更的源端口爲: %d",argument1)
   
   //目的端口
   argument2 := os.Args[2]
   log.Println( "變更後的目的端口爲: %d",argument2)

   // 判斷系統32位還是64位
   bit := 32 << (^uint(0) >> 63)
   fromport, err := strconv.ParseInt(argument1, 10, bit)
   if err != nil {
      log.Println("get pid failed [%s]", err.Error())
      os.Exit(1)
   }

   toport, err := strconv.ParseInt(argument2, 10, bit)
   if err != nil {
      log.Println("get pid failed [%s]", err.Error())
      os.Exit(1)
   }


   fromaddr := fmt.Sprintf(":%d", fromport)
   toaddr := fmt.Sprintf("127.0.0.1:%d", toport)

   fromlistener, err := net.Listen("tcp", fromaddr)

   if err != nil {
      log.Fatal("Unable to listen on: %s, error: %s\n", fromaddr, err.Error())
   }
   defer fromlistener.Close()
   for {
      fromcon, err := fromlistener.Accept()
      if err != nil {
         fmt.Printf("Unable to accept a request, error: %s\n", err.Error())
      } else {
         fmt.Println("new connect:" + fromcon.RemoteAddr().String())
      }

      //這邊最好也做個協程,防止阻塞
      toCon, err := net.Dial("tcp", toaddr)
      if err != nil {
         fmt.Printf("can not connect to %s\n", toaddr)
         continue
      }

      go handleConnection(fromcon, toCon)
      go handleConnection(toCon, fromcon)

   }

}

func handleConnection(r, w net.Conn) {
   defer r.Close()
   defer w.Close()

   var buffer = make([]byte, 100000)
   for {
      n, err := r.Read(buffer)
      if err != nil {
         break
      }

      n, err = w.Write(buffer[:n])
      if err != nil {
         break
      }
   }

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