英文:
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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论