2017-04-21 62 views
0

相信我要么误解如何去做例程工作,如何缓冲读者工作,或两者兼而有之。并发| goroutines | golang |缓冲阅读器

期待所述够程的异步执行(与一个for循环读缓冲器,等待来自服务器的消息的缓冲读取器)

尝试METHOD A客户端之前调用go xyz()拨打服务器;所以xyz()创建缓冲区并开始在后台读取。然后,客户端拨打服务器;服务器发回消息;客户端读取缓冲区,所以,它得到的消息,并打印到控制台

实际发生客户端将消息发送到服务器,但是在读从可能的回复不拿起任何东西缓冲区服务器;所以它是并发运行的,因为我知道for循环没有停止,但它允许执行下一行代码(客户端向服务器发送消息)。

但是当METHOD B我打电话xyz()不能同时和之后的客户端拨号服务器,所有的东西正常工作。客户端从服务器获取消息并打印到控制台。


方法的,我们有顺序:

/////////////步骤1和2是在由go xyz()

称为够程
  1. for循环创建缓冲读者
  2. - 读缓冲器,用于从服务器消息 - 打印ö UT
  3. 客户端拨入服务器

    go xyz(conn, p)

    fmt.Fprintf(conn, "Give me a hash to work on ...")


方法B,我们有顺序:

个/////////////步骤2和3是在由xyz()

  1. 客户称为够程拨打
  2. 将创建缓冲读者
  3. for循环的服务器 - - 读取来自服务器的消息缓冲器 - 打印出

    fmt.Fprintf(conn, "Give me a hash to work on ...")

    xyz(conn, p)




client.go

package main 
import (
    "fmt" 
    "net" 
    "bufio" 
) 

func xyz(conn net.Conn, p []byte) { 
    rd := bufio.NewReader(conn) 
    for { 
    _, err := rd.Read(p) 
    if err == nil { 
     fmt.Printf("SERVER : %s\n", p) 
    } else { 
     fmt.Printf("Some error %v\n", err) 
    } 
    } 
} 

func main() { 
    p := make([]byte, 2048) 
    conn, err := net.Dial("udp", "127.0.0.1:1234") 
    if err != nil { 
     fmt.Printf("Some error %v", err) 
     return 
    } 

    go xyz(conn, p) 
    fmt.Fprintf(conn, "Give me a hash to work on ...") 
} 

server.go

package main 
import (
    "fmt" 
    "net" 
) 


func sendResponse(conn *net.UDPConn, addr *net.UDPAddr, hash string) { 
    _,err := conn.WriteToUDP([]byte("Hello, here is the hash - " + hash), addr) 
    if err != nil { 
     fmt.Printf("Couldn't send response %v", err) 
    } 
} 


func main() { 
    hash := "36"; 
    p := make([]byte, 2048) 
    addr := net.UDPAddr{ 
     Port: 1234, 
     IP: net.ParseIP("127.0.0.1"), 
    } 
    ser, err := net.ListenUDP("udp", &addr) 
    if err != nil { 
     fmt.Printf("Some error %v\n", err) 
     return 
    } 
    for { 
     _, remoteaddr, err := ser.ReadFromUDP(p) 
     fmt.Printf("CLIENT : %v : %s\n", remoteaddr, p) 
     if err != nil { 
      fmt.Printf("Some error %v", err) 
      continue 
     } 
     go sendResponse(ser, remoteaddr, hash) 
    } 
} 

回答

2

The Go Programming Language Specification

Go statements

A “走出去” 的语句开头的函数调用控制的 独立并发线程,或者够程的执行过程中, 相同的地址空间内。

...与常规调用不同,程序执行不会等待 被调用的函数完成。

client.go启动够程xyz然后保持要去main功能终止该节目的结束。该程序不等待xyz goroutine运行或完成。

+0

所以,你暗示在客户端从服务器接收到消息之前,缓冲读取器没有时间启动? –

+0

我在goroutine之后和发送消息给服务器之前试过'time.Sleep(2000)'。仍然没有工作。 –

+1

@MattClendenen:我说''xyx'在'main'结束之前没有很远,程序,因此'xyx'终止。 – peterSO