我正在尝试创建一个服务器并在Go中连接到它,但是当服务器开始运行时,它后面的任何函数都不会被调用,因为启动服务器的函数似乎正在阻塞。我尝试使用goroutine在后台运行服务器,以便可以执行其他代码,但这也不起作用。我收到我不明白的错误
紧急情况:运行时错误:无效的内存地址或nil指针取消引用[信号SIGSEGV:分段违规代码= 0x1 addr = 0x18 pc = 0x496757]
这是我的服务器代码
func RunServer(port string) {
fmt.Println("Launching server...")
ln, err := net.Listen("tcp", port)
conn, _ := ln.Accept()
// run loop forever (or until ctrl-c)
for {
// will listen for message to process ending in newline (\n)
message, _ := bufio.NewReader(conn).ReadString('\n')
// output message received
fmt.Print("Message Received:", string(message))
// sample process for string received
newmessage := strings.ToUpper(message)
// send new string back to client
conn.Write([]byte(newmessage + "\n"))
}
}
这是客户端的代码。
func createInitalClient(port int) {
// run server then create a client that connects to it
portToRunOn := fmt.Sprintf("%s%d", ":", port)
go RunServer(portToRunOn)
}
func main() {
createInitalClient(5000)
// connect to this socket
conn, _ := net.Dial("tcp", "127.0.0.1:5000")
for {
// read in input from stdin
reader := bufio.NewReader(os.Stdin)
fmt.Print("Text to send: ")
text, _ := reader.ReadString('\n')
// send to socket
fmt.Fprintf(conn, text+"\n")
// listen for reply
message, _ := bufio.NewReader(conn).ReadString('\n')
fmt.Print("Message from server: " + message)
}
}
我是在正确执行此操作,还是有其他方法可以执行我要执行的操作?我有点不愿使用goroutine,因为在我的情况下引入异步行为可能是错误的。
编辑1:似乎正在发生此错误,因为客户端试图在启动之前连接到服务器。
编辑2:我(可能)通过在服务器中添加一个布尔通道来修复此问题,该通道在听众开始接受连接之前返回true。然后,如果来自通道的值为true,则客户端仅连接到服务器。在这种情况下,我不确定这是否是正确的解决方法,但它似乎可以正常工作。
您的服务器是在goroutine中启动的,该goroutine是由Go运行时异步生成的,将需要一些时间来计划和执行。具体来说,运行时不会在继续执行main
功能之前等待服务器goroutine启动。
您要么需要:
让您的客户端连接尝试反复连接,直到接受连接为止–实际上是轮询服务器的就绪状态。例如:
// Predeclare "conn" to ensure it remains in scope outside the loop
var conn net.Conn
for {
var err error
conn, err = net.Dial("tcp", "127.0.0.1:5000")
// Failed connection, try again in a second.
// TODO: limit the number of attempts before giving up.
if err != nil {
time.Sleep(time.Second)
continue
}
// Connected successfully. Continue.
break
}
// do something with "conn"
正如您对问题的评论所指出的那样,您的代码在多个地方都忽略了错误值。
请不要在实际的生产代码中执行此操作。返回错误是有原因的,并且可能表明代码外部存在问题,导致您的程序无法正确继续执行。您需要检查错误值,并在返回错误值时采取适当的措施。从函数调用返回的其他值,尤其是标准库中的任何值,如果返回error
的不是,则不太可能有意义nil
。
是的,您最终会写if err != nil
很多东西。这是预料之中的,在某些情况下可以采用多种模式来避免使代码看起来过于重复。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句