我正在阅读Go编程语言的书。在第8.3节中,我们有echo server的代码如下所示:
package main
import (
"bufio"
"fmt"
"log"
"net"
"strings"
"time"
)
func main() {
l, err := net.Listen("tcp", "localhost:8000")
if err != nil {
log.Fatal(err)
}
for {
conn, err := l.Accept()
log.Println("Accepted connection")
if err != nil {
log.Println(err)
continue
}
go handleConn(conn)
}
}
func handleConn(c net.Conn) {
defer c.Close()
br := bufio.NewScanner(c)
for br.Scan() {
echo(c, br.Text(), 1*time.Second)
}
}
func echo(c net.Conn, shout string, delay time.Duration) {
fmt.Fprintln(c, "\t", strings.ToUpper(shout))
time.Sleep(delay)
fmt.Fprintln(c, "\t", shout)
time.Sleep(delay)
fmt.Fprintln(c, "\t", strings.ToLower(shout))
}
字符串
在请求该服务器的书中,我们创建了netcat克隆程序,如下所示:
package main
import (
"io"
"log"
"net"
"os"
)
func main() {
numberOfCommand := os.Args[1:]
if len(numberOfCommand) != 3 {
log.Fatal("Usage: netcat1 <host> <port> <connection-type>")
}
host := numberOfCommand[0]
port := numberOfCommand[1]
connectionType := numberOfCommand[2]
conn, err := net.Dial(connectionType, host+":"+port)
if err != nil {
log.Fatal(err)
}
defer conn.Close()
go mustCopy(conn, os.Stdin)
mustCopy(os.Stdout, conn)
}
func mustCopy(dst io.Writer, src io.Reader) {
if _, err := io.Copy(dst, src); err != nil {
log.Fatal(err)
}
}
型
基本上,你正在发送一些字符串,服务器发送这个字符串的普通,普通和普通版本。它是工作的,但是如果我从go mustCopy(conn,os.Stdin)
中删除go
前缀。它不工作。我认为如果我删除go前缀,所有事情都会按顺序完成。它从stdin向服务器写入一个字符串,然后得到响应,但它不发送字符串或获得响应。
1条答案
按热度按时间sycxhyv71#
请注意,
mustCopy
不会返回,直到出现错误,这发生在连接关闭时。所以当您调用:字符串
第一个
mustCopy
永远不会返回。它是从stdin读取并写入连接的那个。所以你向服务器发送请求,但从不阅读响应。使用go mustCopy(...)
,第一个mustCopy
在一个单独的goroutine中并发运行。第二个mustCopy
阻塞直到连接终止,阅读响应,而第一个从标准输入中读取请求并发送请求。