doubu1950 2018-09-22 15:26
浏览 49
已采纳

创建服务器并连接到它

I'm trying to create a server and connect to it in Go but when the server starts running, no functions after it are called because the function that starts the server appears to be blocking. I tried using a goroutine to run the server in the background so that other code can be executed but that's not really working either. I'm getting an error that I don't understand

panic: runtime error: invalid memory address or nil pointer dereference [signal SIGSEGV: segmentation violation code=0x1 addr=0x18 pc=0x496757]

Here is my code for the server

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 (
)
        message, _ := bufio.NewReader(conn).ReadString('
')

        // 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 + "
"))
    }
}

And here is the code for the client.

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('
')

        // send to socket
        fmt.Fprintf(conn, text+"
")

        // listen for reply
        message, _ := bufio.NewReader(conn).ReadString('
')
        fmt.Print("Message from server: " + message)
    }
}

Am I doing this right or is there another approach to do what I'm trying to do? I'm a little hesistant to use goroutines because introducing async behavior might be wrong in my case.

EDIT 1: looks like this error is happening because the client is trying to connect to the server before it starts.

EDIT 2: I (might have) fixed this by adding a boolean channel in the server that returns true right before the listeners starts accepting connections. Then the client only connects to the server if the value coming from the channel is true. I'm not sure if this is the correct fix in this scenario but it appears to be working.

  • 写回答

1条回答

  • douze1332 2018-09-22 18:10
    关注

    Your server is started in a goroutine, which is spawned asynchronously by the Go runtime and will take some time to be scheduled and executed. Specifically, the runtime will not wait for the server goroutine to be started before continuing execution of the main function.

    You either need to:

    • arrange for the server goroutine to communicate when the server is ready to accept connections – use of a channel is an acceptable mechanism for this; or
    • have your client connection attempt to connect repeatedly until the connection is accepted – in effect polling the server's readiness state. For example:

      // 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 values

    As noted in a comment to your question, your code ignores error values in several places.

    Please don't do this in real production code. Errors are returned for a reason, and may indicate a problem external to your code which prevents your program from properly continuing execution. You need to check for error values and take appropriate action where they are returned. The other value(s) returned from a function call, especially anything in the standard library, are unlikely to be meaningful if the returned error is not nil.

    Yes, you end up writing if err != nil a lot. That's expected, and there are various patterns you can employ in some cases to avoid making your code seem excessively repetitive.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥50 如何增强飞上天的树莓派的热点信号强度,以使得笔记本可以在地面实现远程桌面连接
  • ¥15 MCNP里如何定义多个源?
  • ¥20 双层网络上信息-疾病传播
  • ¥50 paddlepaddle pinn
  • ¥20 idea运行测试代码报错问题
  • ¥15 网络监控:网络故障告警通知
  • ¥15 django项目运行报编码错误
  • ¥15 STM32驱动继电器
  • ¥15 Windows server update services
  • ¥15 关于#c语言#的问题:我现在在做一个墨水屏设计,2.9英寸的小屏怎么换4.2英寸大屏