istio.io/istio@v0.0.0-20240520182934-d79c90f27776/samples/tcp-echo/src/main.go (about) 1 // Copyright Istio Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package main 16 17 import ( 18 "bufio" 19 "fmt" 20 "io" 21 "net" 22 "os" 23 "strings" 24 ) 25 26 // main serves as the program entry point 27 func main() { 28 if len(os.Args) != 3 { 29 fmt.Println("you should run it like: 'main [PORTS...] prefix' , please notice PORTS are comma-delineated , like port 1[,port 2] ") 30 os.Exit(1) 31 } 32 // obtain the port and prefix via program arguments 33 ports := strings.Split(os.Args[1], ",") 34 prefix := os.Args[2] 35 for _, port := range ports { 36 addr := fmt.Sprintf(":%s", port) 37 go serve(addr, prefix) 38 } 39 ch := make(chan struct{}) 40 <-ch 41 } 42 43 // serve starts serving on a given address 44 func serve(addr, prefix string) { 45 // create a tcp listener on the given port 46 listener, err := net.Listen("tcp", addr) 47 if err != nil { 48 fmt.Println("failed to create listener, err:", err) 49 os.Exit(1) 50 } 51 fmt.Printf("listening on %s, prefix: %s\n", listener.Addr(), prefix) 52 53 // listen for new connections 54 for { 55 conn, err := listener.Accept() 56 if err != nil { 57 fmt.Println("failed to accept connection, err:", err) 58 continue 59 } 60 61 // pass an accepted connection to a handler goroutine 62 go handleConnection(conn, prefix) 63 } 64 } 65 66 // handleConnection handles the lifetime of a connection 67 func handleConnection(conn net.Conn, prefix string) { 68 defer conn.Close() 69 reader := bufio.NewReader(conn) 70 for { 71 // read client request data 72 bytes, err := reader.ReadBytes(byte('\n')) 73 if err != nil { 74 if err != io.EOF { 75 fmt.Println("failed to read data, err:", err) 76 } 77 return 78 } 79 fmt.Printf("request: %s", bytes) 80 81 // prepend prefix and send as response 82 line := fmt.Sprintf("%s %s", prefix, bytes) 83 fmt.Printf("response: %s", line) 84 conn.Write([]byte(line)) 85 } 86 }