如何正确地在net.Con中分块消息并防止广播睡眠。

huangapple go评论90阅读模式
英文:

how to properly chunk messages in net.Con & sleep preventing broadcast

问题

更新解决方案:
http://play.golang.org/p/Skgk9reT6c

http://play.golang.org/p/gtWYPXRsKo

没有使用goroutines的版本:
http://play.golang.org/p/Vgne7e3RVO

问题1:为什么消息"YOU'LL NEVER SEE ME!"没有显示?

问题2:一旦我初始化一个客户端,我就会发送这些消息,每个消息都在自己的线程中:

func client() {
  net, _ := net.Dial("tcp", "127.0.0.1:9988")
  go clientBroadcast(net,"123456789101112")
  go clientBroadcast(net,"do dododo do dodo do")
  go clientBroadcast(net,"123456789101112")
  go clientBroadcast(net,"do dododo do dodo do")
  go clientBroadcast(net,"123456789101112")
  go clientBroadcast(net,"TWELVE!")
  time.Sleep(100 * time.Millisecond)
  go clientBroadcast(net,"YOU'LL NEVER SEE ME!")
}

服务器接收并打印它们:

func serverBroadcast(con net.Conn, ch chan string) {
  buf := make([]byte, 1024)
  bytenum, _ := con.Read(buf)
  strin := string(buf[0:bytenum])
  fmt.Printf("\n Server Broadcasting Message {%v}\n",string(strin))
}

为什么服务器显然一次接收到了所有4条消息,而不是一次接收一条?

我得到了这个消息:

Server Broadcasting Message {123456789101112do dododo do dodo
do123456789101112do dododo do dodo do123456789101112TWELVE!}

Server Broadcasting Message {123456789101112do dododo do dodo
do123456789101112do dododo do dodo do123456789101112TWELVE!}

Server Broadcasting Message {123456789101112do dododo do dodo
do123456789101112do dododo do dodo do123456789101112TWELVE!}

然而,我本来以为我应该收到这个(以某种随机顺序,因为它们都是线程化的):

Server Broadcasting Message {123456789101112}

Server Broadcasting Message {do dododo do dodo}

Server Broadcasting Message {123456789101112}

Server Broadcasting Message {do dododo do dodo}

Server Broadcasting Message {TWELVE!}

Server Broadcasting Message {123456789101112}

Server Broadcasting Message {do dododo do dodo}

Server Broadcasting Message {123456789101112}

Server Broadcasting Message {do dododo do dodo}

Server Broadcasting Message {TWELVE!}

Server Broadcasting Message {123456789101112}

Server Broadcasting Message {do dododo do dodo}

Server Broadcasting Message {123456789101112}

Server Broadcasting Message {do dododo do dodo}

Server Broadcasting Message {TWELVE!}

英文:

Updated with solution:
http://play.golang.org/p/Skgk9reT6c

http://play.golang.org/p/gtWYPXRsKo

without goroutines:
http://play.golang.org/p/Vgne7e3RVO

Question 1: Why is it that the message "YOU'LL NEVER SEE ME!" doesn't display?

Question 2: As soon as I initiate a client I send these messages, all on their own threads:

func client() {
  net, _ := net.Dial("tcp", "127.0.0.1:9988")
  go clientBroadcast(net,"123456789101112")
  go clientBroadcast(net,"do dododo do dodo do")
  go clientBroadcast(net,"123456789101112")
  go clientBroadcast(net,"do dododo do dodo do")
  go clientBroadcast(net,"123456789101112")
  go clientBroadcast(net,"TWELVE!")
  time.Sleep(100 * time.Millisecond)
  go clientBroadcast(net,"YOU'LL NEVER SEE ME!")
}

The server receives them and prints them out:

func serverBroadcast(con net.Conn, ch chan string) {
  buf := make([]byte, 1024)
  bytenum, _ := con.Read(buf)
  strin := string(buf[0:bytenum])
  fmt.Printf("\n Server Broadcasting Message {%v}\n",string(strin))
}

How is it that the server is apparently receiving all 4 messages at once and not one at a time?

I'm getting this message:

> Server Broadcasting Message {123456789101112do dododo do dodo
> do123456789101112do dododo do dodo do123456789101112TWELVE!}
>
> Server Broadcasting Message {123456789101112do dododo do dodo
> do123456789101112do dododo do dodo do123456789101112TWELVE!}
>
> Server Broadcasting Message {123456789101112do dododo do dodo
> do123456789101112do dododo do dodo do123456789101112TWELVE!}

However I would have assumed I should have received this (in some random order as they are all threaded)

> Server Broadcasting Message {123456789101112}
>
> Server Broadcasting Message {do dododo do dodo}
>
> Server Broadcasting Message {123456789101112}
>
> Server Broadcasting Message {do dododo do dodo}
>
> Server Broadcasting Message {TWELVE!}
>
> Server Broadcasting Message {123456789101112}
>
> Server Broadcasting Message {do dododo do dodo}
>
> Server Broadcasting Message {123456789101112}
>
> Server Broadcasting Message {do dododo do dodo}
>
> Server Broadcasting Message {TWELVE!}
>
> Server Broadcasting Message {123456789101112}
>
> Server Broadcasting Message {do dododo do dodo}
>
> Server Broadcasting Message {123456789101112}
>
> Server Broadcasting Message {do dododo do dodo}
>
> Server Broadcasting Message {TWELVE!}

答案1

得分: 3

问题在于在这个函数中,你没有读取流中的所有可用数据。你需要多次调用Read来获取所有的数据。

func serverBroadcast(con net.Conn, ch chan string) {
    buf := make([]byte, 1024)
    bytenum, _ := con.Read(buf)
    strin := string(buf[0:bytenum])
    fmt.Printf("\n Server Broadcasting Message {%v}\n", string(strin))
}

然而,如果你这样做,你会发现它会阻塞(playground),例如:

func serverBroadcast(con net.Conn, ch chan string) {
    buf := make([]byte, 1024)
    for {
        bytenum, err := con.Read(buf)
        if err != nil {
            fmt.Printf("Err %v", err)
            return
        }
        strin := string(buf[0:bytenum])
        fmt.Printf("\n Server Broadcasting Message {%v}\n", string(strin))
    }
}

如果你想避免阻塞,你需要在TCP上分隔你的消息,或者在消息之前发送一个计数,以便知道消息的起始和结束位置。

英文:

The problem is that in this function you aren't reading all the data available on the stream. You'll need to call Read more than once to get all the data.

func serverBroadcast(con net.Conn, ch chan string) {
	buf := make([]byte, 1024)
	bytenum, _ := con.Read(buf)
	strin := string(buf[0:bytenum])
	fmt.Printf("\n Server Broadcasting Message {%v}\n", string(strin))
}

However if you do that you'll find it will block, (playground), eg

func serverBroadcast(con net.Conn, ch chan string) {
	buf := make([]byte, 1024)
	for {
		bytenum, err := con.Read(buf)
		if err != nil {
			fmt.Printf("Err %v", err)
			return
		}
		strin := string(buf[0:bytenum])
		fmt.Printf("\n Server Broadcasting Message {%v}\n", string(strin))
	}
}

You need to delimit your messages over TCP, or send a count before the message so know where the messages start and end if you want to avoid blocking

huangapple
  • 本文由 发表于 2014年5月5日 19:50:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/23471733.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定