我正在与多个启动程序一起构建回声算法,从本质上讲,我具有三个函数“对话”,“监听”和“运行算法”。 “交谈”将数据发送到邻居,“侦听”从邻居接收的数据,这两个使用渠道。这些通道在“运行算法”功能中受到监控,该功能决定向谁发送消息以及向谁发送消息。
本质上是这样:
func server(s Node, myChannel chan string){
fmt.Printf("SERVER Launching server... %s:%s \n", s.ip, s.port)
// Start listening
// We do not stop listening until the surrounding function returns (finishes)
ln, _ := net.Listen("tcp", s.ip+":"+s.port)
for {
// Accept connections
fmt.Println("SERVER waiting at ln.Accept()")
conn, err := ln.Accept()
if err != nil {
panic(err)
}
//fmt.Println("SERVER connection accepted")
// Read received message
fmt.Println("SERVER awaiting message")
message, err := bufio.NewReader(conn).ReadString('\n')
fmt.Println("SERVER message received = " + message)
if err != nil {
fmt.Println("the server is broken")
panic(err)
}
if err == nil {
// If the mmessage is not empty, then print it in the shell
if string(message) != "" {
fmt.Println("SERVER message put in channel")
myChannel <- message
}
}
}
对话功能如下:
func client(myNode Node, nbour Node, myChannel chan string) {
for {
// this loop controls the sending of algorithm messages
conn, err = net.Dial("tcp", nbour.ip+":"+nbour.port)
// useful info for the user
//fmt.Println("CLIENT awaiting message to send")
// the the message to send out of the channel
messageToSend := <-myChannel
// send the message
conn.Write([]byte(messageToSend))
fmt.Println("CLIENT SENT ALG MESSAGE = " + messageToSend + "to " + nbour.ip + ":" + nbour.port)
// useful information for the user
//fmt.Printf("CLIENT Message text: " + messageToSend. + "\n")
}
问题是这些连接在头几条消息中起作用,然后在某个任意点一个节点发送了一条消息,而邻居却未收到它,一切都停止了。
因此,我的问题是,为什么连接会任意停止,是否在某处有设置告诉它们保持打开状态多长时间或发送多少消息?还是上面的代码错误地实现了这个目标(尽管就像我说的那样有时候工作正常,实际上有时候算法可以完美地完成,然后我再次运行完全相同的代码,并且卡住了,等待消息到达)。 / p>
答案 0 :(得分:0)
因此,似乎建立连接并然后等待将某些内容放入通道会导致问题。如果您改为等待将某些内容放入通道中,然后(一旦从通道中删除了某些内容)进行连接(并按照@leaf bebop的建议关闭连接),则代码每次运行都很好。 (见下文)
func client(myNode Node, nbour Node, myChannel chan string) {
for {
// this loop controls the sending of algorithm messages
// useful info for the user
//fmt.Println("CLIENT awaiting message to send")
// the message to send out of the channel
messageToSend := <-myChannel
conn, err = net.Dial("tcp", nbour.ip+":"+nbour.port)
// send the message
conn.Write([]byte(messageToSend))
conn.Close()
fmt.Println("CLIENT SENT ALG MESSAGE = " + messageToSend + "to " + nbour.ip + ":" + nbour.port)
// useful information for the user
//fmt.Printf("CLIENT Message text: " + messageToSend. + "\n")
}