Modifique clock2 para admitir parámetros entrantes como números de puerto y luego escriba un programa de wallwall que pueda comunicarse con varios servidores de reloj al mismo tiempo, lea el tiempo de varios servidores y muestre los resultados devueltos por todos los servicios a la vez en una tabla , Similar a la pared del reloj que ves en algunas oficinas. Si tiene servidores distribuidos geográficamente que se pueden usar, deje que estos servidores se ejecuten en máquinas diferentes; o ejecute varias instancias diferentes en la misma máquina, estas instancias escuchan puertos diferentes, pretendiendo estar en diferentes zonas horarias . Así:
$ 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
Código del servidor, admite el parámetro ir a pasar para iniciar varios servidores
$ 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)
}
}
Código de cliente, pegue su primer código de prueba primero
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)
}
Esta vez no se imprimió nada porque el subproceso principal salió directamente. No consideraré el canal por el momento. Realizaré un bucle o haré una pausa en el subproceso principal durante 10 segundos para ver el efecto. El código mejorado es el siguiente:
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
Obtienes el resultado esperado:
Además, vi una implementación de cliente similar en 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
También puede obtener el resultado esperado
Nota:
*io.Copy()
Métodos copias de src
copia a dst
, hasta que src
alcance el final del archivo (EOF) o se produce un error, a continuación, devuelve el primer error (si existe) encontrado cuando el número de bytes copiados y copiadas;
Func Copy (dst Writer, src Reader) (escrito int64, error de error)
* Stdin io.Reader
La entrada del Stdout io.Writer
proceso de comando La salida del Stderr io.Writer
proceso de comando La salida de error del proceso de comando
* El tipo de os.Args [1:] es [] string , que es un segmento de cadena. Puede obtener directamente los parámetros después de la ejecución, con espacios como separador de múltiples elementos
os.Args [0:] incluirá la ruta del programa en sí + parámetros separados por espacios
https://www.cnblogs.com/taoshihan/p/8955365.html