亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

客戶端無法將數據發送到 golang 中的 TCP 服務器?

客戶端無法將數據發送到 golang 中的 TCP 服務器?

Go
不負相思意 2023-06-12 15:36:21
我有 TCP 服務器和客戶端,簡單 TCP 服務器將只接收傳入數據并打印它,客戶端將不斷創建套接字連接并在循環中將數據發送到 TCP 服務器。我得到的信息是,如果 TCP 連接正確關閉,這個過程應該繼續進行而不會出現任何崩潰。但是在從客戶端接收到服務器的一些數據后,客戶端因錯誤而崩潰total times data send: 16373panic: runtime error: invalid memory address or nil pointer dereference[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x10d7594]goroutine 1 [running]:main.sendData()/Users/apple/Desktop/Personal/umbrellaserver/src/tests/clinet.go:178 +0xb4main.main()/Users/apple/Desktop/Personal/umbrellaserver/src/tests/clinet.go:170 +0x2aexit status 2服務器.gopackage mainimport (    "bufio"    "fmt"    "net"    "sync")var wg sync.WaitGroupvar count = 0var timeX string = ""var connQueue = make(chan string)func main() {    tcpListner := startTCPConnection()    incomingTCPListener(tcpListner)}//startTCPConnectionfunc startTCPConnection() net.Listener {    tcpListner, tcpConnectonError := net.Listen("tcp", "localhost:3000")    if tcpConnectonError != nil {        print(tcpConnectonError)        return     }    return tcpListner}//incomingTCPListenerfunc incomingTCPListener(tcpListner net.Listener) {    for {        incomingConnection, incomingConnectionError := tcpListner.Accept()        if incomingConnectionError != nil {            print(incomingConnectionError)            return        }        wg.Add(1)        go processIncomingRequest(incomingConnection)        wg.Wait()    }}//processIncomingRequestfunc processIncomingRequest(connection net.Conn) {    defer connection.Close()    var scanner = bufio.NewScanner(connection)    var blob = ""    for scanner.Scan() {        fmt.Println("sadd")        text := scanner.Text()        blob += text    }    print(blob)    count++    fmt.Println("totalCount", count)    wg.Done()}有什么辦法可以避免這種崩潰,讓它一直運行下去嗎? 我是 Go 的新手,所以如果我犯了任何愚蠢的錯誤,我很抱歉。
查看完整描述

3 回答

?
鴻蒙傳說

TA貢獻1865條經驗 獲得超7個贊

首先,如果你想打印到 stderr,(即你的打印調用),我建議使用 fmt 庫


fmt.Fprintln(os.Stderr, "hello world")

為什么:因為打印功能不能保證留在語言中。1個


其次,通常的做法是將錯誤名稱命名為err,而不必將錯誤拼寫為tcpConnectionError.


connection, connectionError := net.Dial("tcp", "localhost:3000")第三,由于您在服務器中使用 tcp,因此正在偵聽 ipv6 和 ipv4。我至少在 Windows 機器上觀察到連接打開兩個連接,一個用于 ipv4 和 ipv6,然后丟棄 ipv6 連接以支持 ipv4。


最后,當 TCP 連接關閉時,端口不能立即重新使用,因為操作系統必須等待 TIME_WAIT 間隔(最大段生存期,MSL)的持續時間。

您的客戶端代碼正在打開大量非常短暫的 tcp 連接,并且根據您臨時端口范圍的范圍,您的代碼可能會或可能不會崩潰。從16373的數量來看,你有默認范圍。2個


>> sysctl net.inet.ip.portrange.first net.inet.ip.portrange.last

net.inet.ip.portrange.first: 49152

net.inet.ip.portrange.last: 65535

最后,


如果您想避免因端口用完而導致崩潰:

1. 增加端口的臨時范圍

2. 使用 Docker,容器在它們自己的網絡上,因此使用一組不同的端口繞過有限的端口范圍。

3. 在您的客戶端代碼中引入一個自動收報機,以模擬每 x 秒/分鐘的連接


package main


import (

    "fmt"

    "net"

    "time"

)


var count = 0


func testJSON2() string {

    return `Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professor at Hampden-Sydney College in Virginia, looked up one of the more obscure Latin words, consectetur, from a Lorem Ipsum passage, and going through the cites of the word in classical literature, discovered the undoubtable source. Lorem Ipsum comes from sections 1.10.32 and 1.10.33 of "de Finibus Bonorum et Malorum" (The Extremes of Good and Evil) by Cicero, written in 45 BC. This book is a treatise on the theory of ethics, very popular during the Renaissance. The first line of Lorem Ipsum, "Lorem ipsum dolor sit amet..", comes from a line in section 1.10.32. The standard chunk of Lorem Ipsum used since the 1500s is reproduced below for those interested. Sections 1.10.32 and 1.10.33 from "de Finibus Bonorum et Malorum" by Cicero are also reproduced in their exact original form, accompanied by English versions from the 1914 translation by H. Rackham.`

}


func main() {

    max := 1000


    timer1 := time.NewTicker(5 * time.Second)


    i := 0

    for range timer1.C {

        sendData()

        if i == max {

            timer1.Stop()

        }

        i++

    }

}


func sendData() {


    connection, connectionError := net.Dial("tcp", "localhost:3000")

    fmt.Println(connection.LocalAddr())


    if connectionError != nil {

        fmt.Println(connectionError)

        return

    }

    newmessage := testJSON2()

    connection.Write([]byte(newmessage + "\n"))

    count++

    fmt.Println(count)


    err := connection.Close()

    if err != nil {

        fmt.Println(err)

    }

}


查看完整回答
反對 回復 2023-06-12
?
慕姐4208626

TA貢獻1852條經驗 獲得超7個贊

if connectionError != nil {

        fmt.Println(connectionError)

        return 

    }

defer connection.Close()

defer connection.Close() 應該在錯誤檢查之后,因為連接變量可以是 nil incase 撥號返回時出現一些錯誤。


查看完整回答
反對 回復 2023-06-12
?
暮色呼如

TA貢獻1853條經驗 獲得超9個贊

package main


import (

    "bufio"

    "fmt"

    "net"

    "sync"

)


var wg sync.WaitGroup

var count = 0

var timeX string = ""


var connQueue = make(chan string)


func main() {

    tcpListner := startTCPConnection()

    incomingTCPListener(tcpListner)

    wg.Wait()

}


//startTCPConnection

func startTCPConnection() net.Listener {

    tcpListner, tcpConnectonError := net.Listen("tcp", "localhost:3000")

    if tcpConnectonError != nil {

        print(tcpConnectonError)

        // return 

        log.Fatal(tcpConnectonError)

    }

    return tcpListner

}


//incomingTCPListener

func incomingTCPListener(tcpListner net.Listener) {


    for {

        incomingConnection, incomingConnectionError := tcpListner.Accept()

        if incomingConnectionError != nil {

            print(incomingConnectionError)

            return

        }

        wg.Add(1)

        go processIncomingRequest(incomingConnection)

        // wg.Wait()

    }

}


//processIncomingRequest

func processIncomingRequest(connection net.Conn) {


    defer connection.Close()


    var scanner = bufio.NewScanner(connection)


    var blob = ""

    for scanner.Scan() {

        fmt.Println("sadd")

        text := scanner.Text()

        blob += text

    }

    print(blob)

    count++

    fmt.Println("totalCount", count)

    wg.Done()

}


問題出在server.go。我的猜測是您通過在 incomingTCPListener() 函數中調用 wg.Wait() 而不是 main() 來耗盡端口。此外,在 startTCPConnection() 函數中直接返回將導致編譯器錯誤。


查看完整回答
反對 回復 2023-06-12
  • 3 回答
  • 0 關注
  • 162 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號