Modify clock2 to support incoming parameters as port numbers, and then write a clockwall program that can communicate with multiple clock servers at the same time, read time from multiple servers, and display the results returned by all services at once in a table , Similar to the clock wall you see in some offices. If you have geographically distributed servers that can be used, let these servers run on different machines; or run multiple different instances on the same machine, these instances listen to different ports, pretending to be in different time zones . Like this:
$ TZ=US/Eastern ./clock2 -port 8010 &
$ TZ=Asia/Tokyo ./clock2 -port 8020 &
$ TZ=Europe/London ./clock2 -port 8030 &
$ clockwall NewYork=localhost:8010 Tokyo=localhost:8020 London=localhost:8030
Server code, support go run pass parameter to start multiple servers
$ go run clock2.go -port 9090 -city beijing
$ go run clock2.go -port 9089 -city shanghai
/clock2.go
package main
import (
"io"
"log"
"net"
"time"
"strconv"
"fmt"
"flag"
)
var port string
var city string
func init() {
flag.StringVar(&port,"port","default","8090")
flag.StringVar(&city,"city","default","default")
}
func main() {
flag.Parse()//暂停获取参数
fmt.Println(port)
fmt.Println(city)
listenConn(port)
}
func handleConn(conn net.Conn) {
defer conn.Close()
for {
_, err := io.WriteString(conn, city + time.Now().Format("15:34:09\n"))
if err != nil {
return
}
time.Sleep(1 * time.Second)
}
}
func listenConn(port string){
listener, err := net.Listen("tcp", "localhost:" + port)
if err != nil {
log.Fatal(err)
fmt.Print(err)
}
i := 0
for {
conn, err := listener.Accept()
i++
fmt.Println("get new conn" + strconv.Itoa(i))
if err != nil {
log.Print(err)
continue
}
go handleConn(conn)
}
}
Client code, paste your first try code first
package main
import(
"io"
"log"
"net"
"os"
"flag"
"strings"
"fmt"
)
var port string
func init() {
flag.StringVar(&port,"port","default","8090")
}
func main(){
flag.Parse()//暂停获取参数
a := strings.Split(port, ";")
for _,v := range a{
fmt.Println(v)
go portDial(v)
}
}
func mustCopy(dst io.Writer,src io.Reader){
if _,err := io.Copy(dst,src);err != nil{
log.Fatal(err)
}
}
func portDial(po string){
conn,err:= net.Dial("tcp","localhost:" + po)
if err!= nil{
log.Fatal(err)
}
defer conn.Close()
mustCopy(os.Stdout,conn)
}
Nothing was printed out this time, because the main thread directly exited. I will not consider the channel for the time being. I will loop or pause the main thread for 10 seconds to see the effect. The improved code is as follows:
package main
import(
"io"
"log"
"net"
"os"
"flag"
"strings"
"fmt"
"time"
)
var port string
func init() {
flag.StringVar(&port,"port","default","8090")
}
func main(){
flag.Parse()//暂停获取参数
fmt.Println(port)
a := strings.Split(port, ",")
fmt.Println(a)
for _,v := range a{
fmt.Println(v)
go portDial(v)
}
for{
time.Sleep(10 * time.Second)
}
}
func mustCopy(dst io.Writer,src io.Reader){
if _,err := io.Copy(dst,src);err != nil{
log.Fatal(err)
}
}
func portDial(po string){
conn,err:= net.Dial("tcp","localhost:" + po)
if err!= nil{
log.Fatal(err)
}
defer conn.Close()
mustCopy(os.Stdout,conn)
}
$ go run netcat.go -port 9090;9089
You get the expected result:
In addition, I saw a similar client implementation on the Internet
// Netcat1 is a read-only TCP client.
package main
import (
"io"
"log"
"net"
"os"
"strings"
"time"
)
func main() {
for _, v := range os.Args[1:] {
keyValue := strings.Split(v, "=")
go connTcp(keyValue[1])
}
for {
time.Sleep(1 * time.Second)
}
}
func connTcp(uri string) {
conn, err := net.Dial("tcp", uri)
if err != nil {
log.Fatal(err)
}
defer conn.Close()
mustCopy(os.Stdout, conn)
}
func mustCopy(dst io.Writer, src io.Reader) {
if _, err := io.Copy(dst, src); err != nil {
log.Fatal(err)
}
}
$ go run netcat1.go beijing=localhost:9090 hangzhou=localhost:9089
Can also get the expected result
Note:
*io.Copy()
Methods copies from src
copy to dst
, until src
reach the end of file (EOF) or an error occurs, then returns the first error (if any) encountered when the number of bytes copied and copied;
func Copy(dst Writer, src Reader) (written int64, err error)
* Stdin io.Reader
The input of the Stdout io.Writer
command process The output of the Stderr io.Writer
command process The error output of the command process
* The type of os.Args [1:] is [] string , which is a string slice. Can directly get the parameters after go run, with spaces as the separator of multiple elements
os.Args [0:] will include the path of the program itself + parameters separated by spaces
https://www.cnblogs.com/taoshihan/p/8955365.html